Oracle
Cryptographic Toolkit Programmer's Guide Release 2.0.3 A54082-01 |
|
This chapter shows you how to program using the Oracle Cryptographic Toolkit. The following topics are discussed:
The following section describes the typical program flow for those who want to use the Oracle Cryptographic Toolkit and provides program code examples for calling the available functions. Refer to Figure 4-1, "Oracle Cryptographic Toolkit Program Flow", below, for an illustration of how a typical program flows using the Oracle Cryptographic Toolkit.
This section first lists the programming steps to follow when you use the Oracle Cryptographic Toolkit. The balance of this chapter provides the following sample code for your use:
"A Short Example: Generating a detached signature for an array of bytes"
"A Long Example: Using the signature and PK encryption features"
Follow steps 1 - 5 to access and interface with the Oracle Security Server.
... OCIError *error_handle = (OCIError *) NULL; OCISecurity *security_handle = (OCISecurity *) NULL; ... /* * The OCI process and environment has already been initialized. */ OCIHandleAlloc((dvoid *) env_handle, (dvoid **) &error_handle, (ub4) OCI_HTYPE_ERROR, (size_t) 0,(dvoid **) 0), OCIHandleAlloc((dvoid *) env_handle, (dvoid **) &security_handle, (ub4) OCI_HTYPE_SECURITY, (size_t) 0, (dvoid **) 0); OCISecurityInitialize(security_handle, error_handle);
... nzttWallet wallet; ... OCISecurityOpenWallet(security_handle, error_handle, wrllen, wrl, passlen, password, &wallet)
... nzttPersona *persona; ... /* * Use the first persona in the wallet. */ persona = &wallet.list_nzttWallet[0]; OCISecurityOpenPersona(security_handle, error_handle, persona);
... nzttBufferBlock signature; ... memset(&signature, 0, sizeof(signature)); OCISecuritySign(security_handle, error_handle, persona, NZTTCES_END, strlen((char *)"Some data"), "Some data", &signature);
OCISecurityCloseWallet(security_handle, error_handle, &wallet); OCISecurityTerminate(security_handle, error_handle); OCIHandleFree((dvoid *) security_handle, OCI_HTYPE_SECURITY);
The following code sample shows you how to generate a detached signature for an array of bytes. For brevity, errors are checked but are not displayed. Refer to Part III, "Appendices", for complete code examples.
#include <oratypes.h> #ifndef OCI_ORACLE #include <oci.h> #endif #ifndef OCIDFN #include <ocidfn.h> #endif #ifdef __STDC__ #include <ociap.h> #else #include <ocikp.h> #endif static text phrase[] = "This is a static text phrase"; int main(argc, argv) int argc; char *argv[]; { nzttWallet wallet; /* Wallet structure */ nzttBufferBlock signature; /* Detached signature */ nzttPersona *persona = (nzttPersona *)NULL; /* Persona used to sign */ OCIEnv *env_handle = (OCIEnv *)NULL; /* OCI environement handle */ OCIError *error_handle = (OCIError *)NULL; /* OCI error handle */ OCISecurity *security_handle = (OCISecurity *)NULL; /* OCI security handle*/ /* * Clear out the wallet and signature structures so that if an * error occurs before they are used, they are not mistaken for * holding allocated memory. */ memset(&wallet, 0, sizeof(wallet)); memset(&signature, 0, sizeof(signature)); /* * Initialize the OCI process. */ if (OCI_SUCCESS != OCIInitialize((ub4) OCI_DEFAULT,(dvoid *)0,(dvoid *(*)())0, (dvoid *(*)())0, (void(*)())0)) { goto exit; } /* * Initialize the OCI environment. */ if (OCI_SUCCESS != OCIEnvInit((OCIEnv **)&env_handle,(ub4)OCI_DEFAULT, (size_t)0, (dvoid **)0)) { goto exit; } /* * Create an error handle. */ if (OCI_SUCCESS != OCIHandleAlloc((dvoid *)env_handle, (dvoid **)&error_handle, (ub4)OCI_HTYPE_ERROR, (size_t)0, (dvoid **)0)) { goto exit; } /* * Create a security handle */ if (OCI_SUCCESS != OCIHandleAlloc((dvoid *)env_handle, (dvoid **)&security_handle, (ub4)OCI_HTYPE_SECURITY, (size_t)0, (dvoid **)0)) { goto exit; } /* * Initialize the security subsystem. */ if (OCI_SUCCESS != OCISecurityInitialize(security_handle, error_handle)) { goto exit; } /* * Open the wallet. Since NZT_DEFAULT_WRL is used as the wallet * WRL, the platform specific default wallet will be used. Note, * as well, that this wallet has no password (NZT_NO_PASSWORD). */ if (OCI_SUCCESS != OCISecurityOpenWallet(security_handle, error_handle, strlen(NZT_DEFAULT_WRL), NZT_DEFAULT_WRL, strlen(NZT_NO_PASSWORD), NZT_NO_PASSWORD, &wallet)) { goto exit; } /* * Use the first persona in the wallet. */ persona = &wallet->list_nzttWallet[0]; /* * Open the persona and prepare it for use. */ if (OCI_SUCCESS != OCISecurityOpenPersona(security_handle, error_handle, persona)) { goto exit; } /* * Create a detached signature for the phrase. This means that * when the signature is verified, the original phrase will need to * be provided since it is not attached to the signature. The * variable 'signature contains the output. */ if (OCI_SUCCESS != OCISecuritySignDetached(security_handle, error_handle, persona, NZTTCES_END, strlen((char *)phrase), phrase, &signature)) { goto exit; } exit: DISCARD OCISecurityPurgeBlock(security_handle, error_handle, &signature); DISCARD OCISecurityCloseWallet(security_handle, error_handle, &wallet); /* * Free the various handles (if allocated). Delay freeing the error * handle so that errors can be generated until the last possible * moment. */ if (security_handle) { DISCARD OCISecurityTerminate(security_handle, error_handle); DISCARD OCIHandleFree((dvoid *)security_handle, OCI_HTYPE_SECURITY); } if (error_handle) { DISCARD OCIHandleFree((dvoid *)error_handle, OCI_HTYPE_ERROR); } if (env_handle) { DISCARD OCIHandleFree((dvoid *)env_handle, OCI_HTYPE_ENV); } return 0; }
The following code sample demonstrates how to combine two cryptographic features: signing and PK encryption. A digital signature allows you to verify the sender and the contents of the message, but it does not protect the data from being viewed by others. PK encryption is a technique where data is encrypted for a particular recipient. If you use both of these two functions, the resulting data can only be read by the intended recipient, and that recipient can verify who the sender is.
#include <oratypes.h> #ifndef OCI_ORACLE #include <oci.h> #endif #ifndef OCIDFN #include <ocidfn.h> #endif #ifdef __STDC__ #include <ociap.h> #else #include <ocikp.h> #endif static void check_error(); static void error(); static text the_data[] = "This is the data." /* * This structure contains a status number and a string that describes it. */ struct status { sword number_tkzxc1status; /* Status value */ text *string_tkzxc1status; /* String it maps to */ }; typedef struct status status; static status status_array[] = { { OCI_SUCCESS_WITH_INFO, (text *) "OCI_SUCCESS_WITH_INFO" }, { OCI_NO_DATA, (text *) "OCI_NO_DATA" }, { OCI_ERROR, (text *) "OCI_ERROR" }, { OCI_INVALID_HANDLE, (text *) "OCI_INVALID_HANDLE" }, { OCI_NEED_DATA, (text *) "OCI_NEED_DATA" }, { OCI_STILL_EXECUTING, (text *) "OCI_STILL_EXECUTING" }, { OCI_CONTINUE, (text *) "OCI_CONTINUE" }, { 0, (text *) NULL } }; /* * Check the return value of a function. Generate an error if it fails. */ #define CHECK_ERROR(func_, string_) \ if ((status = (func_)) != OCI_SUCCESS) \ { \ check_error(error_handle, env_handle, status, (text *) string_);\ goto exit; \ } else int main(argc, argv) int argc; char *argv[]; { nzttWallet wallet; /* Wallet structure */ nzttBufferBlock signature; /* Attached signature */ nzttBufferBlock encryption; /* PK encrypted signature */ nzttIdentity recipient; /* Recipient identity */ nzttPersona *persona = (nzttPersona *)NULL; /* Persona used to sign */ OCIEnv *env_handle = (OCIEnv *)NULL; /* OCI environement handle */ OCIError *error_handle = (OCIError *)NULL; /* OCI error handle */ OCISecurity *security_handle = (OCISecurity *)NULL; /* OCI security handle*/ /* * Clear out the wallet and signature structures so that if an * error occurs before they are used, they are not mistaken for * holding allocated memory. */ memset(&wallet, 0, sizeof(wallet)); memset(&signature, 0, sizeof(signature)); memset(&encrypted, 0, sizeof(encrypted)); memset(&recipient, 0, sizeof(recipient); /* * Initialize the OCI process. */ CHECK_ERROR(OCIInitialize((ub4) OCI_DEFAULT,(dvoid *)0,(dvoid *(*)())0, (dvoid *(*)())0, (void(*)())0), "Could not initialize process."); /* * Initialize the OCI environment. */ CHECK_ERROR(OCIEnvInit((OCIEnv **)&env_handle,(ub4)OCI_DEFAULT, (size_t)0, (dvoid **)0), "Could not initialize environment."); /* * Create an error handle. */ CHECK_ERROR(OCIHandleAlloc((dvoid *)env_handle, (dvoid **)&error_handle, (ub4)OCI_HTYPE_ERROR, (size_t)0, (dvoid **)0), "Could not allocate error handle."); /* * Create a security handle */ CHECK_ERROR(OCIHandleAlloc((dvoid *)env_handle, (dvoid **)&security_handle, (ub4)OCI_HTYPE_SECURITY, (size_t)0, (dvoid **)0), "Could not allocate security handle."); /* * Initialize the security subsystem. */ CHECK_ERROR(OCISecurityInitialize(security_handle, error_handle), "Could not initialize security."); /* * Open the wallet. Since NZT_DEFAULT_WRL is used as the wallet * WRL, the platform specific default wallet will be used. Note, * as well, that this wallet has no password (NZT_NO_PASSWORD). */ CHECK_ERROR(OCISecurityOpenWallet(security_handle, error_handle, strlen(NZT_DEFAULT_WRL), NZT_DEFAULT_WRL, strlen(NZT_NO_PASSWORD), NZT_NO_PASSWORD, &wallet), "Could not open wallet."); /* * Use the first persona in the wallet. */ persona = &wallet->list_nzttWallet[0]; /* * Open the persona and prepare it for use. */ CHECK_ERROR(OCISecurityOpenPersona(security_handle, error_handle, persona), "Could not open persona."); /* * Sign the data. */ CHECK_ERROR(OCISecuritySign(security_handle, error_handle, persona, NZTTCES_END, strlen((char *)the_data), the_data, &signature), "Could not sign data."); /* * Create a recipient identity by looking up a distinguished name in OSS. */ CHECK_ERROR(OCISecurityGetIdentity(security_handle, error_handle, strlen(receiver), receiver, &recipient), "Could not get identity for recipient."); /* * Using the recipient, PKEncrypt the signature. */ CHECK_ERROR(OCISecurityPKEncrypt(security_handle, error_handle, 1, &recipient, NZTCES_END, signature.usedlen_nzttbufferblock, signature.buffer_nzttbufferblock, &encrypted), "Could not PKEncrypt."); exit: DISCARD OCISecurityPurgeBlock(security_handle, error_handle, &signature); DISCARD OCISecurityPurgeBlock(security_handle, error_handle, &encrypted); DISCARD OCISecurityAbortIdentity(security_handle, error_handle, &recipient); DISCARD OCISecurityCloseWallet(security_handle, error_handle, &wallet); /* * Free the various handles (if allocated). Delay freeing the error * handle so that errors can be generated until the last possible * moment. */ if (security_handle) { DISCARD OCISecurityTerminate(security_handle, error_handle); DISCARD OCIHandleFree((dvoid *)security_handle, OCI_HTYPE_SECURITY); } if (error_handle) { DISCARD OCIHandleFree((dvoid *)error_handle, OCI_HTYPE_ERROR); } if (env_handle) { DISCARD OCIHandleFree((dvoid *)env_handle, OCI_HTYPE_ENV); } return 0; } static void check_error(error_handle, env_handle, retstatus, message) OCIError *error_handle; /* IN: error handle */ OCIEnv *env_handle; /* IN: environment handle (OPTIONAL) */ sword retstatus; /* IN: status returned by function */ text *message; /* IN: message to be printed with error */ { status *statusp; sword found; sb4 error_code; text error_string[256]; switch (retstatus) { case OCI_SUCCESS: /* * Should never get here because the macro does the checking. */ break; case OCI_ERROR: error_code = 0; if (error_handle) { DISCARD OCIErrorGet((dvoid *)error_handle, 1, (text *)NULL, &error_code, &error_string[0], sizeof(error_string), OCI_HTYPE_ERROR); } /* * If no error was obtained using the error handle, use the * environment handle (if available). */ if ((error_code == 0) && env_handle) { DISCARD OCIErrorGet((dvoid *)env_handle, 1, (text *)NULL, &error_code, &error_string[0], sizeof(error_string), OCI_HTYPE_ENV); } if (error_code) { error(error_string, message); } else { /* * In some cases, such as failure to allocate a handle, * the exact error is not available. */ error((text *)"OCI_ERROR returned\n", message); } break; default: for (statusp = &tkzxc1_status_array[0], found = 0; statusp->string_tkzxc1status; statusp++) { if (statusp->number_tkzxc1status == retstatus) { DISCARD puts((char *)statusp->string_tkzxc1status); return; } } DISCARD sprintf((char *)error_string, "Error %d returned\n", retstatus); error(error_string, message); break; } return; } static void error(errormsg, message) text *errormsg; /* IN: Error to print out */ text *message; /* IN: Accompanying message (OPTIONAL) */ { if (message) { DISCARD printf ("%s: %s", (char *) message, (char *) errormsg); } else { DISCARD fputs ((char *) errormsg, stdout); } return; }
|
Copyright © 1997 Oracle Corporation. All Rights Reserved. |
|