RSA BSAFE Micro Edition Suite

Streamlined security for mobile and embedded devices

Search  Print

frombuf.c

/* $Id: frombuf.c,v 1.33 2005/06/30 06:55:42 gsingh Exp $ */
/*
 * Copyright (C) 1998-2003 RSA Security Inc.
 *
 * This file shall only be used to demonstrate how to interface to an
 * RSA Security Inc. licensed development product.
 *
 * You have a royalty-free right to use, reproduce and distribute this
 * demonstration file, provided that you agree that RSA Security Inc.
 * has no warranty, implied or otherwise, or liability for this
 * demonstration file (including any modified version).  This software
 * is provided "as is" without warranties or representations of any
 * kind. RSA Security disclaims all conditions and warranties, statutory
 * and otherwise, both express and implied, with respect to the software,
 * its quality and performance, including but not limited to, all
 * implied warranties of merchantability, fitness for a particular
 * purpose, title and noninfringement of third party rights. Without
 * limiting the foregoing, RSA Security does not warrant that the
 * software is error-free or that errors in the product will be
 * corrected. You agree that RSA Security shall not be liable for any
 * direct, indirect, incidental, special, consequential, punitive or
 * other damages whatsoever resulting from your use of this software
 * or any modified version.
 *
 *
 */

#include "r_prod.h"
#ifndef NO_PEM
#include "r_passwd.h"

char *test_wtls_certificate[] =
{
    "-----BEGIN WTLS CERTIFICATE-----",
    "AQIBAAQGQyA9IEFVOG36jDpPgmwBAAQGQyA9IEFVAgAAAwEAAQBAvcooR53q6/Mg",
    "sqbHNtb7nXWHX5N53U2e3WhfPFuMMdtyZCMB9WxxUebOR3r1QzrsbY38+eTOgPg9",
    "oa3x+bKYJQBAU6OLA5BfD07DYkgylNk2lO6wznGGR/+25Br9kZSYXlXuiMAd9Qm1",
    "qEP/yJzl9cryA+fOd08IKkNPnCGztN5DoQ == ",
    "-----END WTLS CERTIFICATE-----"
};
#define N_test_wtls_certificate \
    (int)(sizeof(test_wtls_certificate)/sizeof(test_wtls_certificate[0]))

char *test_x509_certificate[] =
{
    "-----BEGIN CERTIFICATE-----",
    "MIIBiDCB8gIBADANBgkqhkiG9w0BAQQFADANMQswCQYDVQQGEwJBVTAeFw0wMTA1",
    "MDkwMTA1MTFaFw0wMTA2MDgwMTA1MTFaMA0xCzAJBgNVBAYTAkFVMIGfMA0GCSqG",
    "SIb3DQEBAQUAA4GNADCBiQKBgQDzPHX6E45JKbotHyLJHmkRY4mV/uzuvO8HucUm",
    "2wi3IrZ4Cpx/rLK78P9cizDZD2mH3pjASZAWgsGRJKvnGgiFTGg54FDppV1GFlee",
    "KLVSUVYuMFHt/n3jKjvLQ1GEDuFKpMeStTsskDbDQ7gKlsa6dc7dK7h+vIRfnFez",
    "c9g1/wIDAQABMA0GCSqGSIb3DQEBBAUAA4GBAAyhL6kFrsxRO1mSAByeyTMkMesz",
    "r9cPPfwE1aTFa+nNTDVR4NWXN/ccrKi7+FO/Rged6hJB5Unk8L5be6u0/SToyeZa",
    "iY3amp48RgbMEbylRVUq5fsMKn3yKhfbzc567B/234ljaDQQU0ohA3FlpHc65CDw",
    "wYnfeslJ0MZyppqK",
    "-----END CERTIFICATE-----"
};

#define N_test_x509_certificate \
    (int)(sizeof(test_x509_certificate)/sizeof(test_x509_certificate[0]))

char *test_privatekey[] =
{
    "-----BEGIN RSA PRIVATE KEY-----",
    "MIIBOgIBAAJBAL3KKEed6uvzILKmxzbW+511h1+Ted1Nnt1oXzxbjDHbcmQjAfVs",
    "cVHmzkd69UM67G2N/PnkzoD4PaGt8fmymCUCAwEAAQJAbfmuzZEciA0ibWNnHMgG",
    "lX99Kkzy2OIZpILObNM/scNP/obP45hKPLp7T0ryzRTDdtEizRLJcCmHn4Cc0+YC",
    "AQIhAOhXx0iKwq6oBixUH/TReQpkxnB+nIPAdkkwCotbu/d1AiEA0R0xL2WJ5zGH",
    "z8czFI9CZD+KRlUQKYMQDwYaSN8yt/ECIFB7x66bUqEJ10mXwpId1d4B1rO1SCZj",
    "jxX/LEfl+RDZAiBwwkgCYcNRylCMhsKRhIptWiHquPWlHMos/8JupwRHUQIhANXY",
    "60ZidPu9cYtYba2+oydEj0BE77gMr3Buxxo+aLha",
    "-----END RSA PRIVATE KEY-----"
};
#define N_test_privatekey \
    (int)(sizeof(test_privatekey)/sizeof(test_privatekey[0]))

char *test_encrypted_privatekey[] =
{
    "-----BEGIN RSA PRIVATE KEY-----",
    "Proc-Type: 4,ENCRYPTED",
    "DEK-Info: DES-EDE3-CBC,1E533F0A0A00D90B",
    "",
    "p2asbIUd6CSAf+N87jxKc1/Cxvmv2u/SIJkdcQUGMntGKT02IRS97sxqqBntYr1m",
    "UW+9pJBmCLDPJTheO9X7gYJhr/QUVboo44KxO2XMhC4nBiao46MJ9uRG5H6WOMg1",
    "j0FwM9XZN/qUmZAxzZ3GGckw16XOUVUKgGLqb0H3y9+nGniuLSJLaE/FehUwJwFA",
    "BnTbS9YEzpY+NYal7MIGpUKxqKs6QdQY86zJZDoxPg4WRBQ2oMrx2Ux+qnyPkHju",
    "vz6urBFcBYoneYv+D8A22EEtF5RPiatMDOc5h3TlUPx0Mjn3beL5IkMWXHKPpqrb",
    "0N8P+ppwvgG8LrO7/hDii0RDvGdtDkgY+6bRDrKIqU3vqjgkGdqetolf2XxziFIC",
    "RCKOhIXmcmZTLKOGYi7KjPbhTQv1MsYSN2Bx/wzZ8JM=",
    "-----END RSA PRIVATE KEY-----"
};
#define N_test_encrypted_privatekey \
    (int)(sizeof(test_encrypted_privatekey)/sizeof(test_encrypted_privatekey[0]))

int passphrase_cb(char *buf, int len, char *prompt, int verify);
int print_cert_info(BIO *bio, R_CERT *cert);

/*
 * Main sample program entry point.
 *
 * @param argc  [In]  The number of arguments typed on the command line.
 * @param argv  [In]  The array of individual arguments from the command line.
 * @return  0 indicates success.<br>
 *          1 indicates error.
 *
 * @note    If there was an error, the error value is displayed where possible.
 */
int main(int argc, char **argv)
{
    R_LIB_CTX  *lib_ctx       = NULL;
    R_CERT_CTX *wtls_cert_ctx = NULL;
    R_CERT_CTX *x509_cert_ctx = NULL;
    R_CERT     *wtls_cert     = NULL;
    R_CERT     *x509_cert     = NULL;
    R_PKEY_CTX *pkey_ctx      = NULL;
    R_PKEY     *pkey          = NULL;
    R_PKEY     *enc_pkey      = NULL;
    BIO        *bio_err       = NULL;
    BIO        *mem           = NULL;
    int         ret = R_ERROR_FAILED;
    int         i;

    /*
     * Create BIO to stderr. BIOs are the Basic Input/Output mechanism provided
     * by RSA and are recommended for all input and output from applications.
     */
    if ((bio_err = BIO_new_fp(stderr, BIO_NOCLOSE)) == NULL)
    {
        ret = R_ERROR_ALLOC_FAILURE;
        goto err;
    }

    /*
     * Create the library context. Retrieve the default resource list and
     * create a library context to provide access to all configurable aspects
     * of the library.
     */
    if ((ret = PRODUCT_LIBRARY_NEW(PRODUCT_NON_FIPS_140_MODE_RESOURCE_LIST(), 0,
        &lib_ctx)) != R_ERROR_NONE)
    {
        goto err;
    }

    /* Create a memory buffer BIO */
    if ((mem = BIO_new_mem()) == NULL)
    {
        ret = R_ERROR_ALLOC_FAILURE;
        goto err;
    }

#ifndef NO_WTLSCERT
    /*
     * Load and print a WTLS certificate from a buffer:
     *     - Create the specific certificate context.
     *     - Copy the certificate into the memory BIO.
     *     - Read the certificate from the memory BIO to a certificate object.
     *     - Print the certificate by writing it in text format.
     */

    /* Create a new WLTS certificate context */
    if ((ret = R_CERT_CTX_new(lib_ctx, R_RES_FLAG_DEF, R_CERT_TYPE_WTLS,
        &wtls_cert_ctx)) != R_ERROR_NONE)
    {
        goto err;
    }

    /* Print the certificate into the memory buffer BIO */
    for (i = 0; i < N_test_wtls_certificate; i++)
    {
        BIO_printf(mem, "%s\n", test_wtls_certificate[i]);
    }

    /* Load the certificate from the memory buffer */
    ret = R_CERT_read(wtls_cert_ctx, mem, R_CERT_TYPE_WTLS,
                R_FORMAT_PEM, &wtls_cert);

    /* Print the certificate */
    if ((ret == R_ERROR_NONE) && (wtls_cert != NULL))
    {
        R_CERT_write(wtls_cert, bio_err, R_FORMAT_TEXT, NULL);
    }
    else
    {
        BIO_printf(bio_err, "Failed to load the certificate - exiting\n");
        goto err;
    }

    /* Reuse the memory buffer BIO */
    BIO_reset(mem);
#endif /* NO_WTLSCERT */

#ifndef NO_X509CERT
    /*
     * Load and print an X.509 certificate from a buffer:
     *     - Create the specific certificate context.
     *     - Copy the certificate into the memory BIO.
     *     - Read the certificate from the memory BIO to a certificate object.
     *     - Print the certificate by writing it in text format.
     */

   /* Create a new X.509 certificate context */
    if ((ret = R_CERT_CTX_new(lib_ctx, R_RES_FLAG_DEF, R_CERT_TYPE_X509,
        &x509_cert_ctx)) != R_ERROR_NONE)
    {
        goto err;
    }

    /* Print the certificate into the memory buffer BIO */
    for (i = 0; i < N_test_x509_certificate; i++)
    {
        BIO_printf(mem, "%s\n", test_x509_certificate[i]);
    }

    /* Load the certificate from the memory buffer */
    ret = R_CERT_read(x509_cert_ctx, mem, R_CERT_TYPE_X509,
        R_FORMAT_PEM, &x509_cert);

    /* Print the certificate */
    if ((ret == R_ERROR_NONE) && (x509_cert != NULL))
    {
        R_CERT_write(x509_cert, bio_err, R_FORMAT_TEXT, NULL);
    }
    else
    {
        BIO_printf(bio_err, "Failed to load the certificate - exiting\n");
        goto err;
    }

    /* Reuse the memory buffer BIO */
    BIO_reset(mem);

#endif /* NO_X509CERT */

    /*
     * Load and print a private key from a buffer:
     *     - Create the key context.
     *     - Copy the key into the memory BIO.
     *     - Read the key from the memory BIO to a key object.
     *     - Print the key by writing it in text format.
     */

    /* Create a new key context */
    if ((ret = R_PKEY_CTX_new(lib_ctx, R_RES_FLAG_DEF, R_PKEY_TYPE_RSA,
        &pkey_ctx)) != R_ERROR_NONE)
    {
        goto err;
    }

    /* Print the private key into the memory buffer BIO */
    for (i = 0; i < N_test_privatekey; i++)
    {
        BIO_printf(mem, "%s\n", test_privatekey[i]);
    }

    /* Load the private key from the memory buffer */
    ret = R_PKEY_from_bio(mem, pkey_ctx, &pkey, R_PKEY_TYPE_RSA, R_FORMAT_PEM);

    /* Print the private key */
    if ((ret == R_ERROR_NONE) && (pkey != NULL))
    {
        BIO_printf(bio_err, "Read the private key\n");
        R_PKEY_print(bio_err, pkey, R_FORMAT_TEXT, NULL);
    }
    else
    {
        BIO_printf(bio_err, "Failed to load the private key - exiting\n");
        goto err;
    }

    /* Reuse the memory buffer BIO */
    BIO_reset(mem);

    /*
     * Load and print an encrypted private key from a buffer:
     *     - Use the existing key context.
     *     - Set up the password callback.
     *     - Copy the key into the memory BIO.
     *     - Read the key from the memory BIO to a key object.
     *     - Print the key by writing it in text format.
     */

    /* Print the encrypted private key into the memory buffer BIO */
    for (i = 0; i < N_test_encrypted_privatekey; i++)
    {
        BIO_printf(mem, "%s\n", test_encrypted_privatekey[i]);
    }

    /* Set the application-specific password callback function */
    R_passwd_set_cb(passphrase_cb);

    /* Load the encrypted private key from the memory buffer */
    ret = R_PKEY_from_bio(mem, pkey_ctx, &enc_pkey, R_PKEY_TYPE_RSA,
        R_FORMAT_PEM);

    /* Print the encrypted private key */
    if ((ret == R_ERROR_NONE) && (enc_pkey != NULL))
    {
        BIO_printf(bio_err, "Read the encrypted private key\n");
        R_PKEY_print(bio_err, enc_pkey, R_FORMAT_TEXT, NULL);
    }
    else
    {
        BIO_printf(bio_err, "Failed to load the encrypted private key - exiting\n");
        goto err;
    }

    /*
     * Clean up. Report errors if there is an output stream using both the
     * error and the string representation. Destroy the dynamically allocated
     * objects and return an exit code.
     */
err:

    if ((bio_err != NULL) && (ret != R_ERROR_NONE))
    {
        BIO_printf(bio_err, "Error: (%d) %s\n", ret,
            R_LIB_CTX_get_error_string(lib_ctx, R_RES_MOD_ID_LIBRARY, ret));
    }

    if (bio_err != NULL)
    {
        BIO_free(bio_err);
    }
    if (mem != NULL)
    {
        BIO_free(mem);
    }
    if (wtls_cert != NULL)
    {
        R_CERT_free(wtls_cert);
    }
    if (x509_cert != NULL)
    {
        R_CERT_free(x509_cert);
    }
    if (pkey != NULL)
    {
        R_PKEY_free(pkey);
    }
    if (enc_pkey != NULL)
    {
        R_PKEY_free(enc_pkey);
    }
    if (wtls_cert_ctx != NULL)
    {
        R_CERT_CTX_free(wtls_cert_ctx);
    }
    if (x509_cert_ctx != NULL)
    {
        R_CERT_CTX_free(x509_cert_ctx);
    }
    if (pkey_ctx != NULL)
    {
        R_PKEY_CTX_free(pkey_ctx);
    }

    if (lib_ctx != NULL)
    {
        PRODUCT_LIBRARY_FREE(lib_ctx);
    }

    return(R_ERROR_EXIT_CODE(ret));
}

/*
 * Provides a passphrase for decryption. In this case, a hard-coded passphrase
 * of "test1234" is used.
 *
 * @param  buf       [Out] The returned passphrase buffer.
 * @param  len       [In]  The size of the passphrase buffer.
 * @param  prompt    [In]  The unused prompt string.
 * @param  verify    [In]  The unused verify flag.
 *
 * @returns  R_ERROR_NONE indicates success.<br>
 *           See @ref R_ERROR_IDS for valid values.
 */
int passphrase_cb(char *buf, int len, char *prompt, int verify)
{
    char *passphrase = "test1234";
    int   passphrase_len;

    passphrase_len = Strlen(passphrase);

    /*
     * Check that there is sufficient space for the passphrase including a
     * NULL terminator in the buffer, otherwise truncate
     */
    if (passphrase_len > (len - 1))
    {
        passphrase_len = (len - 1);
    }

    Memcpy(buf, passphrase, passphrase_len + 1);

    return (R_ERROR_NONE);
}
#else /* !NO_PEM */
/*
 * Main sample program entry point when NO_PEM is defined.
 *
 * @param argc  [In]  The number of arguments typed on the command line.
 * @param argv  [In]  The array of individual arguments from the command line.
 * @return
 *          0 indicates success.<br>
 *          1 indicates error.
 *
 * @note    This sample if not useful if NO_PEM is defined.
 */
int main(int argc, char **argv)
{
    return (0);
}
#endif /* !NO_PEM */

Copyright (c) 1999-2005 RSA Security Inc. All rights reserved. 072-001001-2100-001-000 - 2.1