(linenum→info "unix/slp.c:2238")

openssl/0.9.8g/engines/e_4758cca.c

    1: /* Author: Maurice Gittens <maurice@gittens.nl>                       */
    2: /* ====================================================================
    3:  * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
    4:  *
    5:  * Redistribution and use in source and binary forms, with or without
    6:  * modification, are permitted provided that the following conditions
    7:  * are met:
    8:  *
    9:  * 1. Redistributions of source code must retain the above copyright
   10:  *    notice, this list of conditions and the following disclaimer. 
   11:  *
   12:  * 2. Redistributions in binary form must reproduce the above copyright
   13:  *    notice, this list of conditions and the following disclaimer in
   14:  *    the documentation and/or other materials provided with the
   15:  *    distribution.
   16:  *
   17:  * 3. All advertising materials mentioning features or use of this
   18:  *    software must display the following acknowledgment:
   19:  *    "This product includes software developed by the OpenSSL Project
   20:  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
   21:  *
   22:  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
   23:  *    endorse or promote products derived from this software without
   24:  *    prior written permission. For written permission, please contact
   25:  *    licensing@OpenSSL.org.
   26:  *
   27:  * 5. Products derived from this software may not be called "OpenSSL"
   28:  *    nor may "OpenSSL" appear in their names without prior written
   29:  *    permission of the OpenSSL Project.
   30:  *
   31:  * 6. Redistributions of any form whatsoever must retain the following
   32:  *    acknowledgment:
   33:  *    "This product includes software developed by the OpenSSL Project
   34:  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
   35:  *
   36:  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
   37:  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   38:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   39:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
   40:  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   41:  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   42:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
   43:  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   44:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
   45:  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   46:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
   47:  * OF THE POSSIBILITY OF SUCH DAMAGE.
   48:  * ====================================================================
   49:  *
   50:  * This product includes cryptographic software written by Eric Young
   51:  * (eay@cryptsoft.com).  This product includes software written by Tim
   52:  * Hudson (tjh@cryptsoft.com).
   53:  *
   54:  */
   55: 
   56: #include <stdio.h>
   57: #include <string.h>
   58: #include <openssl/crypto.h>
   59: #include <openssl/dso.h>
   60: #include <openssl/x509.h>
   61: #include <openssl/objects.h>
   62: #include <openssl/engine.h>
   63: #include <openssl/rand.h>
   64: #ifndef OPENSSL_NO_RSA
   65: #include <openssl/rsa.h>
   66: #endif
   67: #include <openssl/bn.h>
   68: 
   69: #ifndef OPENSSL_NO_HW
   70: #ifndef OPENSSL_NO_HW_4758_CCA
   71: 
   72: #ifdef FLAT_INC
   73: #include "hw_4758_cca.h"
   74: #else
   75: #include "vendor_defns/hw_4758_cca.h"
   76: #endif
   77: 
   78: #include "e_4758cca_err.c"
   79: 
   80: static int ibm_4758_cca_destroy(ENGINE *e);
   81: static int ibm_4758_cca_init(ENGINE *e);
   82: static int ibm_4758_cca_finish(ENGINE *e);
   83: static int ibm_4758_cca_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void));
   84: 
   85: /* rsa functions */
   86: /*---------------*/
   87: #ifndef OPENSSL_NO_RSA
   88: static int cca_rsa_pub_enc(int flen, const unsigned char *from,
   89:                 unsigned char *to, RSA *rsa,int padding);
   90: static int cca_rsa_priv_dec(int flen, const unsigned char *from,
   91:                 unsigned char *to, RSA *rsa,int padding);
   92: static int cca_rsa_sign(int type, const unsigned char *m, unsigned int m_len,
   93:                 unsigned char *sigret, unsigned int *siglen, const RSA *rsa);
   94: static int cca_rsa_verify(int dtype, const unsigned char *m, unsigned int m_len,
   95:                 unsigned char *sigbuf, unsigned int siglen, const RSA *rsa);
   96: 
   97: /* utility functions */
   98: /*-----------------------*/
   99: static EVP_PKEY *ibm_4758_load_privkey(ENGINE*, const char*,
  100:                 UI_METHOD *ui_method, void *callback_data);
  101: static EVP_PKEY *ibm_4758_load_pubkey(ENGINE*, const char*,
  102:                 UI_METHOD *ui_method, void *callback_data);
  103: 
  104: static int getModulusAndExponent(const unsigned char *token, long *exponentLength,
  105:                 unsigned char *exponent, long *modulusLength,
  106:                 long *modulusFieldLength, unsigned char *modulus);
  107: #endif
  108: 
  109: /* RAND number functions */
  110: /*-----------------------*/
  111: static int cca_get_random_bytes(unsigned char*, int );
  112: static int cca_random_status(void);
  113: 
  114: #ifndef OPENSSL_NO_RSA
  115: static void cca_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad,
  116:                 int idx,long argl, void *argp);
  117: #endif
  118: 
  119: /* Function pointers for CCA verbs */
  120: /*---------------------------------*/
  121: #ifndef OPENSSL_NO_RSA
  122: static F_KEYRECORDREAD keyRecordRead;
  123: static F_DIGITALSIGNATUREGENERATE digitalSignatureGenerate;
  124: static F_DIGITALSIGNATUREVERIFY digitalSignatureVerify;
  125: static F_PUBLICKEYEXTRACT publicKeyExtract;
  126: static F_PKAENCRYPT pkaEncrypt;
  127: static F_PKADECRYPT pkaDecrypt;
  128: #endif
  129: static F_RANDOMNUMBERGENERATE randomNumberGenerate;
  130: 
  131: /* static variables */
  132: /*------------------*/
  133: static const char *CCA4758_LIB_NAME = NULL;
  134: static const char *get_CCA4758_LIB_NAME(void)
  135:         {
  136:         if(CCA4758_LIB_NAME)
  137:                 return CCA4758_LIB_NAME;
  138:         return CCA_LIB_NAME;
  139:         }
  140: static void free_CCA4758_LIB_NAME(void)
  141:         {
  142:         if(CCA4758_LIB_NAME)
  143:                 OPENSSL_free((void*)CCA4758_LIB_NAME);
  144:         CCA4758_LIB_NAME = NULL;
  145:         }
  146: static long set_CCA4758_LIB_NAME(const char *name)
  147:         {
  148:         free_CCA4758_LIB_NAME();
  149:         return (((CCA4758_LIB_NAME = BUF_strdup(name)) != NULL) ? 1 : 0);
  150:         }
  151: #ifndef OPENSSL_NO_RSA
  152: static const char* n_keyRecordRead = CSNDKRR;
  153: static const char* n_digitalSignatureGenerate = CSNDDSG;
  154: static const char* n_digitalSignatureVerify = CSNDDSV;
  155: static const char* n_publicKeyExtract = CSNDPKX;
  156: static const char* n_pkaEncrypt = CSNDPKE;
  157: static const char* n_pkaDecrypt = CSNDPKD;
  158: #endif
  159: static const char* n_randomNumberGenerate = CSNBRNG;
  160: 
  161: #ifndef OPENSSL_NO_RSA
  162: static int hndidx = -1;
  163: #endif
  164: static DSO *dso = NULL;
  165: 
  166: /* openssl engine initialization structures */
  167: /*------------------------------------------*/
  168: 
  169: #define CCA4758_CMD_SO_PATH             ENGINE_CMD_BASE
  170: static const ENGINE_CMD_DEFN    cca4758_cmd_defns[] = {
  171:         {CCA4758_CMD_SO_PATH,
  172:                 "SO_PATH",
  173:                 "Specifies the path to the '4758cca' shared library",
  174:                 ENGINE_CMD_FLAG_STRING},
  175:         {0, NULL, NULL, 0}
  176:         };
  177: 
  178: #ifndef OPENSSL_NO_RSA
  179: static RSA_METHOD ibm_4758_cca_rsa =
  180:         {
  181:         "IBM 4758 CCA RSA method",
  182:         cca_rsa_pub_enc,
  183:         NULL,
  184:         NULL,
  185:         cca_rsa_priv_dec,
  186:         NULL, /*rsa_mod_exp,*/
  187:         NULL, /*mod_exp_mont,*/
  188:         NULL, /* init */
  189:         NULL, /* finish */
  190:         RSA_FLAG_SIGN_VER,       /* flags */
  191:         NULL, /* app_data */
  192:         cca_rsa_sign, /* rsa_sign */
  193:         cca_rsa_verify, /* rsa_verify */
  194:         NULL /* rsa_keygen */
  195:         };
  196: #endif
  197: 
  198: static RAND_METHOD ibm_4758_cca_rand =
  199:         {
  200:         /* "IBM 4758 RAND method", */
  201:         NULL, /* seed */
  202:         cca_get_random_bytes, /* get random bytes from the card */
  203:         NULL, /* cleanup */
  204:         NULL, /* add */
  205:         cca_get_random_bytes, /* pseudo rand */
  206:         cca_random_status, /* status */
  207:         };
  208: 
  209: static const char *engine_4758_cca_id = "4758cca";
  210: static const char *engine_4758_cca_name = "IBM 4758 CCA hardware engine support";
  211: #ifndef OPENSSL_NO_DYNAMIC_ENGINE 
  212: /* Compatibility hack, the dynamic library uses this form in the path */
  213: static const char *engine_4758_cca_id_alt = "4758_cca";
  214: #endif
  215: 
  216: /* engine implementation */
  217: /*-----------------------*/
  218: static int bind_helper(ENGINE *e)
  219:         {
  220:         if(!ENGINE_set_id(e, engine_4758_cca_id) ||
  221:                         !ENGINE_set_name(e, engine_4758_cca_name) ||
  222: #ifndef OPENSSL_NO_RSA
  223:                         !ENGINE_set_RSA(e, &ibm_4758_cca_rsa) ||
  224: #endif
  225:                         !ENGINE_set_RAND(e, &ibm_4758_cca_rand) ||
  226:                         !ENGINE_set_destroy_function(e, ibm_4758_cca_destroy) ||
  227:                         !ENGINE_set_init_function(e, ibm_4758_cca_init) ||
  228:                         !ENGINE_set_finish_function(e, ibm_4758_cca_finish) ||
  229:                         !ENGINE_set_ctrl_function(e, ibm_4758_cca_ctrl) ||
  230: #ifndef OPENSSL_NO_RSA
  231:                         !ENGINE_set_load_privkey_function(e, ibm_4758_load_privkey) ||
  232:                         !ENGINE_set_load_pubkey_function(e, ibm_4758_load_pubkey) ||
  233: #endif
  234:                         !ENGINE_set_cmd_defns(e, cca4758_cmd_defns))
  235:                 return 0;
  236:         /* Ensure the error handling is set up */
  237:         ERR_load_CCA4758_strings();
  238:         return 1;
  239:         }
  240: 
  241: #ifdef OPENSSL_NO_DYNAMIC_ENGINE
  242: static ENGINE *engine_4758_cca(void)
  243:         {
  244:         ENGINE *ret = ENGINE_new();
  245:         if(!ret)
  246:                 return NULL;
  247:         if(!bind_helper(ret))
  248:                 {
  249:                 ENGINE_free(ret);
  250:                 return NULL;
  251:                 }
  252:         return ret;
  253:         }
  254: 
  255: void ENGINE_load_4758cca(void)
  256:         {
  257:         ENGINE *e_4758 = engine_4758_cca();
  258:         if (!e_4758) return;
  259:         ENGINE_add(e_4758);
  260:         ENGINE_free(e_4758);
  261:         ERR_clear_error();   
  262:         }
  263: #endif
  264: 
  265: static int ibm_4758_cca_destroy(ENGINE *e)
  266:         {
  267:         ERR_unload_CCA4758_strings();
  268:         free_CCA4758_LIB_NAME();
  269:         return 1;
  270:         }
  271: 
  272: static int ibm_4758_cca_init(ENGINE *e)
  273:         {
  274:         if(dso)
  275:                 {
  276:                 CCA4758err(CCA4758_F_IBM_4758_CCA_INIT,CCA4758_R_ALREADY_LOADED);
  277:                 goto err;
  278:                 }
  279: 
  280:         dso = DSO_load(NULL, get_CCA4758_LIB_NAME(), NULL, 0);
  281:         if(!dso)
  282:                 {
  283:                 CCA4758err(CCA4758_F_IBM_4758_CCA_INIT,CCA4758_R_DSO_FAILURE);
  284:                 goto err;
  285:                 }
  286: 
  287: #ifndef OPENSSL_NO_RSA
  288:         if(!(keyRecordRead = (F_KEYRECORDREAD)
  289:                                 DSO_bind_func(dso, n_keyRecordRead)) ||
  290:                         !(randomNumberGenerate = (F_RANDOMNUMBERGENERATE)
  291:                                 DSO_bind_func(dso, n_randomNumberGenerate)) ||
  292:                         !(digitalSignatureGenerate = (F_DIGITALSIGNATUREGENERATE)
  293:                                 DSO_bind_func(dso, n_digitalSignatureGenerate)) ||
  294:                         !(digitalSignatureVerify = (F_DIGITALSIGNATUREVERIFY)
  295:                                 DSO_bind_func(dso, n_digitalSignatureVerify)) ||
  296:                         !(publicKeyExtract = (F_PUBLICKEYEXTRACT)
  297:                                 DSO_bind_func(dso, n_publicKeyExtract)) ||
  298:                         !(pkaEncrypt = (F_PKAENCRYPT)
  299:                                 DSO_bind_func(dso, n_pkaEncrypt)) ||
  300:                         !(pkaDecrypt = (F_PKADECRYPT)
  301:                                 DSO_bind_func(dso, n_pkaDecrypt)))
  302:                 {
  303:                 CCA4758err(CCA4758_F_IBM_4758_CCA_INIT,CCA4758_R_DSO_FAILURE);
  304:                 goto err;
  305:                 }
  306: #else
  307:         if(!(randomNumberGenerate = (F_RANDOMNUMBERGENERATE)
  308:                                 DSO_bind_func(dso, n_randomNumberGenerate)))
  309:                 {
  310:                 CCA4758err(CCA4758_F_IBM_4758_CCA_INIT,CCA4758_R_DSO_FAILURE);
  311:                 goto err;
  312:                 }
  313: #endif
  314: 
  315: #ifndef OPENSSL_NO_RSA
  316:         hndidx = RSA_get_ex_new_index(0, "IBM 4758 CCA RSA key handle",
  317:                 NULL, NULL, cca_ex_free);
  318: #endif
  319: 
  320:         return 1;
  321: err:
  322:         if(dso)
  323:                 DSO_free(dso);
  324:         dso = NULL;
  325: 
  326: #ifndef OPENSSL_NO_RSA
  327:         keyRecordRead = (F_KEYRECORDREAD)0;
  328:         digitalSignatureGenerate = (F_DIGITALSIGNATUREGENERATE)0;
  329:         digitalSignatureVerify = (F_DIGITALSIGNATUREVERIFY)0;
  330:         publicKeyExtract = (F_PUBLICKEYEXTRACT)0;
  331:         pkaEncrypt = (F_PKAENCRYPT)0;
  332:         pkaDecrypt = (F_PKADECRYPT)0;
  333: #endif
  334:         randomNumberGenerate = (F_RANDOMNUMBERGENERATE)0;
  335:         return 0;
  336:         }
  337: 
  338: static int ibm_4758_cca_finish(ENGINE *e)
  339:         {
  340:         free_CCA4758_LIB_NAME();
  341:         if(!dso)
  342:                 {
  343:                 CCA4758err(CCA4758_F_IBM_4758_CCA_FINISH,
  344:                                 CCA4758_R_NOT_LOADED);
  345:                 return 0;
  346:                 }
  347:         if(!DSO_free(dso))
  348:                 {
  349:                 CCA4758err(CCA4758_F_IBM_4758_CCA_FINISH,
  350:                                 CCA4758_R_UNIT_FAILURE);
  351:                 return 0;
  352:                 }
  353:         dso = NULL;
  354: #ifndef OPENSSL_NO_RSA
  355:         keyRecordRead = (F_KEYRECORDREAD)0;
  356:         randomNumberGenerate = (F_RANDOMNUMBERGENERATE)0;
  357:         digitalSignatureGenerate = (F_DIGITALSIGNATUREGENERATE)0;
  358:         digitalSignatureVerify = (F_DIGITALSIGNATUREVERIFY)0;
  359:         publicKeyExtract = (F_PUBLICKEYEXTRACT)0;
  360:         pkaEncrypt = (F_PKAENCRYPT)0;
  361:         pkaDecrypt = (F_PKADECRYPT)0;
  362: #endif
  363:         randomNumberGenerate = (F_RANDOMNUMBERGENERATE)0;
  364:         return 1;
  365:         }
  366: 
  367: static int ibm_4758_cca_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
  368:         {
  369:         int initialised = ((dso == NULL) ? 0 : 1);
  370:         switch(cmd)
  371:                 {
  372:         case CCA4758_CMD_SO_PATH:
  373:                 if(p == NULL)
  374:                         {
  375:                         CCA4758err(CCA4758_F_IBM_4758_CCA_CTRL,
  376:                                         ERR_R_PASSED_NULL_PARAMETER);
  377:                         return 0;
  378:                         }
  379:                 if(initialised)
  380:                         {
  381:                         CCA4758err(CCA4758_F_IBM_4758_CCA_CTRL,
  382:                                         CCA4758_R_ALREADY_LOADED);
  383:                         return 0;
  384:                         }
  385:                 return set_CCA4758_LIB_NAME((const char *)p);
  386:         default:
  387:                 break;
  388:                 }
  389:         CCA4758err(CCA4758_F_IBM_4758_CCA_CTRL,
  390:                         CCA4758_R_COMMAND_NOT_IMPLEMENTED);
  391:         return 0;
  392:         }
  393: 
  394: #ifndef OPENSSL_NO_RSA
  395: 
  396: #define MAX_CCA_PKA_TOKEN_SIZE 2500
  397: 
  398: static EVP_PKEY *ibm_4758_load_privkey(ENGINE* e, const char* key_id,
  399:                         UI_METHOD *ui_method, void *callback_data)
  400:         {
  401:         RSA *rtmp = NULL;
  402:         EVP_PKEY *res = NULL;
  403:         unsigned char* keyToken = NULL;
  404:         unsigned char pubKeyToken[MAX_CCA_PKA_TOKEN_SIZE];
  405:         long pubKeyTokenLength = MAX_CCA_PKA_TOKEN_SIZE;
  406:         long keyTokenLength = MAX_CCA_PKA_TOKEN_SIZE;
  407:         long returnCode;
  408:         long reasonCode;
  409:         long exitDataLength = 0;
  410:         long ruleArrayLength = 0;
  411:         unsigned char exitData[8];
  412:         unsigned char ruleArray[8];
  413:         unsigned char keyLabel[64];
  414:         unsigned long keyLabelLength = strlen(key_id);
  415:         unsigned char modulus[256];
  416:         long modulusFieldLength = sizeof(modulus);
  417:         long modulusLength = 0;
  418:         unsigned char exponent[256];
  419:         long exponentLength = sizeof(exponent);
  420: 
  421:         if (keyLabelLength > sizeof(keyLabel))
  422:                 {
  423:                 CCA4758err(CCA4758_F_IBM_4758_LOAD_PRIVKEY,
  424:                 CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
  425:                 return NULL;
  426:                 }
  427: 
  428:         memset(keyLabel,' ', sizeof(keyLabel));
  429:         memcpy(keyLabel, key_id, keyLabelLength);
  430: 
  431:         keyToken = OPENSSL_malloc(MAX_CCA_PKA_TOKEN_SIZE + sizeof(long));
  432:         if (!keyToken)
  433:                 {
  434:                 CCA4758err(CCA4758_F_IBM_4758_LOAD_PRIVKEY,
  435:                                 ERR_R_MALLOC_FAILURE);
  436:                 goto err;
  437:                 }
  438: 
  439:         keyRecordRead(&returnCode, &reasonCode, &exitDataLength,
  440:                 exitData, &ruleArrayLength, ruleArray, keyLabel,
  441:                 &keyTokenLength, keyToken+sizeof(long));
  442: 
  443:         if (returnCode)
  444:                 {
  445:                 CCA4758err(CCA4758_F_IBM_4758_LOAD_PRIVKEY,
  446:                         CCA4758_R_FAILED_LOADING_PRIVATE_KEY);
  447:                 goto err;
  448:                 }
  449: 
  450:         publicKeyExtract(&returnCode, &reasonCode, &exitDataLength,
  451:                 exitData, &ruleArrayLength, ruleArray, &keyTokenLength,
  452:                 keyToken+sizeof(long), &pubKeyTokenLength, pubKeyToken);
  453: 
  454:         if (returnCode)
  455:                 {
  456:                 CCA4758err(CCA4758_F_IBM_4758_LOAD_PRIVKEY,
  457:                         CCA4758_R_FAILED_LOADING_PRIVATE_KEY);
  458:                 goto err;
  459:                 }
  460: 
  461:         if (!getModulusAndExponent(pubKeyToken, &exponentLength,
  462:                         exponent, &modulusLength, &modulusFieldLength,
  463:                         modulus))
  464:                 {
  465:                 CCA4758err(CCA4758_F_IBM_4758_LOAD_PRIVKEY,
  466:                         CCA4758_R_FAILED_LOADING_PRIVATE_KEY);
  467:                 goto err;
  468:                 }
  469: 
  470:         (*(long*)keyToken) = keyTokenLength;
  471:         rtmp = RSA_new_method(e);
  472:         RSA_set_ex_data(rtmp, hndidx, (char *)keyToken);
  473: 
  474:         rtmp->e = BN_bin2bn(exponent, exponentLength, NULL);
  475:         rtmp->n = BN_bin2bn(modulus, modulusFieldLength, NULL);
  476:         rtmp->flags |= RSA_FLAG_EXT_PKEY;
  477: 
  478:         res = EVP_PKEY_new();
  479:         EVP_PKEY_assign_RSA(res, rtmp);
  480: 
  481:         return res;
  482: err:
  483:         if (keyToken)
  484:                 OPENSSL_free(keyToken);
  485:         if (res)
  486:                 EVP_PKEY_free(res);
  487:         if (rtmp)
  488:                 RSA_free(rtmp);
  489:         return NULL;
  490:         }
  491: 
  492: static EVP_PKEY *ibm_4758_load_pubkey(ENGINE* e, const char* key_id,
  493:                         UI_METHOD *ui_method, void *callback_data)
  494:         {
  495:         RSA *rtmp = NULL;
  496:         EVP_PKEY *res = NULL;
  497:         unsigned char* keyToken = NULL;
  498:         long keyTokenLength = MAX_CCA_PKA_TOKEN_SIZE;
  499:         long returnCode;
  500:         long reasonCode;
  501:         long exitDataLength = 0;
  502:         long ruleArrayLength = 0;
  503:         unsigned char exitData[8];
  504:         unsigned char ruleArray[8];
  505:         unsigned char keyLabel[64];
  506:         unsigned long keyLabelLength = strlen(key_id);
  507:         unsigned char modulus[512];
  508:         long modulusFieldLength = sizeof(modulus);
  509:         long modulusLength = 0;
  510:         unsigned char exponent[512];
  511:         long exponentLength = sizeof(exponent);
  512: 
  513:         if (keyLabelLength > sizeof(keyLabel))
  514:                 {
  515:                 CCA4758err(CCA4758_F_IBM_4758_LOAD_PUBKEY,
  516:                         CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL);
  517:                 return NULL;
  518:                 }
  519: 
  520:         memset(keyLabel,' ', sizeof(keyLabel));
  521:         memcpy(keyLabel, key_id, keyLabelLength);
  522: 
  523:         keyToken = OPENSSL_malloc(MAX_CCA_PKA_TOKEN_SIZE + sizeof(long));
  524:         if (!keyToken)
  525:                 {
  526:                 CCA4758err(CCA4758_F_IBM_4758_LOAD_PUBKEY,
  527:                                 ERR_R_MALLOC_FAILURE);
  528:                 goto err;
  529:                 }
  530: 
  531:         keyRecordRead(&returnCode, &reasonCode, &exitDataLength, exitData,
  532:                 &ruleArrayLength, ruleArray, keyLabel, &keyTokenLength,
  533:                 keyToken+sizeof(long));
  534: 
  535:         if (returnCode)
  536:                 {
  537:                 CCA4758err(CCA4758_F_IBM_4758_LOAD_PUBKEY,
  538:                                 ERR_R_