Oracle Cryptographic Toolkit Programmer's Guide
Release 2.0.3
A54082-01

Library

Product

Contents

Index


Prev Next

4
Using the Oracle Cryptographic Toolkit

This chapter shows you how to program using the Oracle Cryptographic Toolkit. The following topics are discussed:

4.1 Basic Oracle Cryptographic Toolkit Program Flow

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.

Figure 4-1 Oracle Cryptographic Toolkit Program Flow

4.2 Programming Examples

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"

4.2.1 Using the Oracle Cryptographic Toolkit

Follow steps 1 - 5 to access and interface with the Oracle Security Server.

  1. Once the OCI process has been initialized with OCIInitialize and the environment has been initialized with OCIEnvInit (refer to the Programmer's Guide to the Oracle Call Interface), the security handle can be created with OCIHandleAlloc and initialized with OCISecurityInitialize. The security handle is used with subsequent calls to the Oracle Cryptographic Toolkit.
  2.       ... 
          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);
     
    
  3. Typically, an application will first need to open a wallet in order to get its persona and gain access to the list of trusted identities. The wallet location is specified through a Wallet Resource Locator (WRL), and if the contents have been protected with a password, the correct password must be provided as well.
  4.       ... 
          nzttWallet wallet;
          ... 
     
          OCISecurityOpenWallet(security_handle, error_handle,
                                wrllen, wrl,
                                passlen, password,
                                &wallet)
    
    
  5. Next, an application will choose a persona from the wallet and open it to prepare it for use.
  6.       ...
          nzttPersona *persona;
          ...
     
          /*
           * Use the first persona in the wallet.
           */
          persona = &wallet.list_nzttWallet[0];
     
          OCISecurityOpenPersona(security_handle, error_handle, persona);
        
    
  7. The application is now in a position to perform a cryptographic function such as signing some data:
  8.       ...
          nzttBufferBlock signature;
          ...
     
          memset(&signature, 0, sizeof(signature));
          OCISecuritySign(security_handle, error_handle, persona,
                          NZTTCES_END, strlen((char *)"Some data"),
                          "Some data", &signature);
     
    
  9. During termination, the application should call OCIHandleFree to deallocate the security handle once the wallet has been closed and the security subsystem has been terminated.
  10.       OCISecurityCloseWallet(security_handle, error_handle, &wallet); 
          OCISecurityTerminate(security_handle, error_handle); 
          OCIHandleFree((dvoid *) security_handle, OCI_HTYPE_SECURITY); 
    

4.2.2 A Short Example: Generating a detached signature for an array of bytes

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; 
} 

4.2.3 A Long Example: Using the signature and PK encryption features

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; 
} 




Prev

Next
Oracle
Copyright © 1997 Oracle Corporation.
All Rights Reserved.

Library

Product

Contents

Index