RSA BSAFE Micro Edition Suite

Streamlined security for mobile and embedded devices

Search  Print

evpkey2rpkey.c

/* $Id: evpkey2rpkey.c,v 1.4 2005/08/03 00:44:24 ronl Exp $ */

/*
 * Copyright (C) 1999-2003 RSA Security Inc. All rights reserved.
 *
 * This work contains proprietary information of RSA Security.
 * Distribution is limited to authorized licensees of RSA
 * Security. Any unauthorized reproduction, distribution or
 * modification of this work is strictly prohibited.
 */

#include "r_prod.h"

static unsigned char public_key[158] =
{
    0x30,0x81,0x9B,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,
    0x01,0x01,0x05,0x00,0x03,0x81,0x89,0x00,0x30,0x81,0x85,0x02,0x7E,0x00,
    0x92,0xCE,0x7A,0xC1,0xAE,0x83,0x3E,0x5A,0xAA,0x89,0x83,0x57,0xAC,0x25,
    0x01,0x76,0x0C,0xAD,0xAE,0x8E,0x2C,0x37,0xCE,0xEB,0x35,0x78,0x64,0x54,
    0x03,0xE5,0x84,0x40,0x51,0xC9,0xBF,0x8F,0x08,0xE2,0x8A,0x82,0x08,0xD2,
    0x16,0x86,0x37,0x55,0xE9,0xB1,0x21,0x02,0xAD,0x76,0x68,0x81,0x9A,0x05,
    0xA2,0x4B,0xC9,0x4B,0x25,0x66,0x22,0x56,0x6C,0x88,0x07,0x8F,0xF7,0x81,
    0x59,0x6D,0x84,0x07,0x65,0x70,0x13,0x71,0x76,0x3E,0x9B,0x77,0x4C,0xE3,
    0x50,0x89,0x56,0x98,0x48,0xB9,0x1D,0xA7,0x29,0x1A,0x13,0x2E,0x4A,0x11,
    0x59,0x9C,0x1E,0x15,0xD5,0x49,0x54,0x2C,0x73,0x3A,0x69,0x82,0xB1,0x97,
    0x39,0x9C,0x6D,0x70,0x67,0x48,0xE5,0xDD,0x2D,0xD6,0xC8,0x1E,0x7B,0x02,
    0x03,0x01,0x00,0x01,
};

/* Global BIO for output to standard error */
BIO *bio_err;

int main(int argc, char *argv[])
{
    int ret = R_ERROR_FAILED;                /* Function return value */
    BIO *bio_out = NULL;
    R_LIB_CTX *lib_ctx = NULL;          /* Pointer to library context */
    EVP_PKEY *pubkey = NULL;

    R_PKEY_CTX       *key_ctx   = NULL;
    R_PKEY_TYPE       keytype;
    R_FORMAT          keyform;
    R_PKEY           *rpkey = NULL;
    unsigned char    *p = NULL;
    unsigned char    *key_buffer = NULL;
    unsigned char    *key_bufptr = NULL;
    int               key_length = 0;
    unsigned int      consumed_len;

    keytype      = R_PKEY_TYPE_RSA;
    keyform      = R_FORMAT_BINARY;

    /* Create an output channel */
    if ((bio_err = BIO_new_fp(stderr, BIO_NOCLOSE)) == NULL)
    {
        goto end;
    }
    BIO_set_flags(bio_err, BIO_FLAGS_FLUSH_ON_WRITE);

    /* Create an output channel */
    if ((bio_out = BIO_new_fp(stdout, BIO_NOCLOSE)) == NULL)
    {
        goto end;
    }
    BIO_set_flags(bio_out, BIO_FLAGS_FLUSH_ON_WRITE);

    /* Initialize the SSL library using the default resources */
    if (PRODUCT_LIBRARY_NEW(PRODUCT_DEFAULT_RESOURCE_LIST(), R_RES_FLAG_DEF,
        &lib_ctx) != R_ERROR_NONE)
    {
        BIO_printf(bio_err, "Unable to create library context\n");
        goto end;
    }

    /* Create a new key context */
    if ((ret = R_PKEY_CTX_new(lib_ctx, R_RES_FLAG_DEF, keytype, &key_ctx)) !=
        R_ERROR_NONE)
    {
        BIO_printf(bio_out, "Key context new failure\n");
        goto end;
    }

    BIO_printf(bio_out, "\nLoad Binary Public Key to a EVP_KEY\n");
    p = public_key;
    if ((SSLCERT_PKEY_from_PUBKEY_binary(EVP_PKEY_RSA, &pubkey,
        (unsigned char **) &p, sizeof(public_key))) == NULL)
    {
        goto end;
    }

    /* Convert EVP_KEY to R_PKEY */
    BIO_printf(bio_out, "\nConvert EVP_KEY to R_PKEY\n\n");

    /* Allocate a temporary buffer for the public key data */
    key_length = SSLCERT_PKEY_to_PUBKEY_binary(pubkey, NULL);

    key_buffer = (unsigned char *)Malloc((unsigned int)key_length);
    if (key_buffer == NULL)
    {
        /* The buffer cannot be allocated so exit immediately */
        SSLerr(SSLCERT_F_PKEY_FROM_BINARY, ERR_R_MALLOC_FAILURE);
        goto end;
    }
    key_bufptr = key_buffer;

    /* Output the key data to the tmp buffer in ASN.1 format */
    key_length = SSLCERT_PKEY_to_binary(pubkey, &key_buffer);
    BIO_printf(bio_out, "Key length of binary representation is %d\n\n",
                         key_length);
    key_buffer = key_bufptr;

    /*
     * Create the public key object and load the key. Creating a private key
     * object enables the private key to be read from memory and converted into
     * an R_PKEY object.
     */
    if ((ret = R_PKEY_from_public_key_binary( key_ctx, R_PKEY_FL_DEFAULT,
                                              R_PKEY_TYPE_RSA, key_length,
                                              key_buffer, &consumed_len,
                                              &rpkey)) != R_ERROR_NONE)
    {
        BIO_printf(bio_out, "R_PKEY_from_binary failure\n");
        goto end;
    }

    /* Process the data read from the client */
    BIO_printf(bio_out, "Done\n");

    /* Set program success */
    ret = R_ERROR_NONE;

end:

    /* On error output the error stack */
    if ((ret != R_ERROR_NONE) && (bio_err != NULL))
    {
        ERR_print_errors(bio_err);
    }

    if (key_bufptr)
    {
        Free (key_bufptr);
    }

    /* Free the BIOs for standard out and error */
    if (bio_out != NULL)
    {
        BIO_free(bio_out);
    }

    if (pubkey != NULL)
    {
        SSLCERT_PKEY_free(pubkey);
    }

    if (rpkey != NULL)
    {
        R_PKEY_free(rpkey);
    }

    if (key_ctx != NULL)
    {