RSA BSAFE Micro Edition Suite

Streamlined security for mobile and embedded devices

Search  Print

Get SSLCERT Certificate from R_CERT

This sample demonstrates how to obtain certificates in SSLCERT format from certificates in R_CERT format.

Sample Description:
-------------------
This sample shows how to obtain certificates in SSLCERT format 
from certificates in R_CERT format.

Procedure:
----------
 1) Initialize the library.
 2) Create the R_PKEY and R_CERT contexts.
 3) Load and create a private key and certificate - via 
    rcertandkey.h.
 4) Get and print the subject and issuer name.
 5) Confirm the private key and certificate are a matching pair.
 6) Load the error text strings.
 7) Convert the R_CERT certificate to binary.
 8) Convert the binary certificate to an SSLCERT certificate.
 9) Convert the R_PKEY private key to binary.
10) Convert the binary private key to an EVP_KEY private key.
11) Confirm the EVP_KEY private key and the SSLCERT certificate
    are a matching pair - this confirms the conversion was
    successful.

/* $Id: rcert2sslcert.c,v 1.7 2005/08/09 23:25:38 build 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"
#include "rcertandkey.h"      /* Built-in R_CERT certificate and private key */

#define  CERT_NAME_BUF_LEN 256

/* 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 */
    SSLCERT *sslcert = NULL;               /* Pointer to certificate */
    SSLCERT_NAME *xn;
    SSLCERT_NAME *sn;
    EVP_PKEY *pkey = NULL;                 /* Pointer to private key */
    R_CERT_CTX       *cert_ctx  = NULL;
    R_CERT           *rcert     = NULL;
    R_PKEY_CTX       *key_ctx   = NULL;
    R_CERT_TYPE       certtype;
    R_FORMAT          certform;
    R_PKEY_TYPE       keytype;
    R_FORMAT          keyform;
    R_PKEY           *rpkey     = NULL;
    int               cert_length = 0;
    int               consumed_len;
    unsigned char    *cert_buffer = NULL;
    unsigned char    *cert_bufptr = NULL;
    char buf[CERT_NAME_BUF_LEN] = {'\0'};
    unsigned char    *key_buffer = NULL;
    unsigned char    *key_bufptr = NULL;
    int               key_length = 0;
    char             *issuerName = NULL;
    char             *subjectName = NULL;

    certtype     = R_CERT_TYPE_X509;
    certform     = R_FORMAT_BINARY;
    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_err, "Key context new failure\n");
        goto end;
    }

    /* Create a new certificate context */
    if ((ret = R_CERT_CTX_new(lib_ctx, R_RES_FLAG_DEF, certtype, &cert_ctx)) !=
        R_ERROR_NONE)
    {
        BIO_printf(bio_err, "Certificate context new failure\n");
        goto end;
    }

    /*
     * 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_binary( key_ctx, R_PKEY_FL_DEFAULT, R_PKEY_TYPE_RSA,
        sizeof(priv_key_data), priv_key_data, (unsigned int *)&consumed_len,
        &rpkey)) != R_ERROR_NONE)
    {
        BIO_printf(bio_err, "R_PKEY_from_binary failure\n");
        goto end;
    }

    BIO_printf(bio_out, "Loaded a R_PKEY - done\n");

    /*
     * Create a certificate object. Read the binary representation of the
     * certificate and convert it to an R_CERT object. If the object does not
     * exist (that is, cert==NULL), an R_CERT object is created.
     */
    if ((ret = R_CERT_from_binary(cert_ctx, R_FLAG_SHARE_DATA, R_CERT_TYPE_X509,
        sizeof(certificate), certificate, (unsigned int *)&consumed_len,
        &rcert)) != R_ERROR_NONE)
    {
        BIO_printf(bio_err,
            "R_CERT_from_binary failure for signer certificate\n");
        goto end;
    }

    BIO_printf(bio_out, "Loaded a R_CERT - done\n");

    if ((ret = R_CERT_subject_name_to_string(rcert, sizeof(buf),
                                             (char *)buf)) != R_ERROR_NONE)
    {
        goto end;
    }
    BIO_printf(bio_out, "subject: %s\n", buf);

    if ((ret = R_CERT_issuer_name_to_string(rcert, sizeof(buf), (char *)buf)) !=
        R_ERROR_NONE)
    {
        goto end;
    }
    BIO_printf(bio_out, "issuer: %s\n", buf);

    if (R_CERT_is_matching_private_key(rcert, rpkey))
    {
        BIO_printf(bio_out, "R_CERT and R_PKEY match!\n");
    }
    else
    {
        BIO_printf(bio_err, "Failed: R_CERT / R_PKEY match\n");
        goto end;
    }


#ifndef SSLC_SMALL_CODE
    SSL_load_error_strings();
#endif /* !SSLC_SMALL_CODE */

    /* Convert SSLCERT to R_CERT */
    BIO_printf(bio_out, "\n\nConvert R_CERT to SSLC\n\n");
    /* Convert R_CERT to binary */
    if ((ret = R_CERT_to_binary(rcert, 0, NULL, (unsigned int *)&cert_length))
        != R_ERROR_NONE)
    {
        goto end;
    }

    if ((cert_buffer = (unsigned char *)Malloc(cert_length)) == NULL)
    {
        ret = R_ERROR_ALLOC_FAILURE;
        goto end;
    }

    /*
     * Take a copy of binary buffer as the following call progresses
     * the pointer. The original pointer to Free must be kept in order to
     * Malloc data at the end.
     */
    cert_bufptr = cert_buffer;

    if ((ret = R_CERT_to_binary(rcert, cert_length, cert_buffer,
                                (unsigned int *)&consumed_len)) != R_ERROR_NONE)
    {
        goto end;
    }

    if (SSLCERT_from_binary(&sslcert, &cert_buffer, cert_length) == NULL)
    {
        BIO_printf(bio_err,"error - failed to convert SSLCERT_from_binary\n");
        goto end;
    }

    BIO_printf(bio_out,"Converted SSLCERT_from_binary\n");

    /* Print issuer and subject name */
    xn = SSLCERT_get_issuer_name(sslcert);
    issuerName = SSLCERT_NAME_oneline(xn,buf,CERT_NAME_BUF_LEN);
    if (issuerName == NULL)
    {
        BIO_printf(bio_err, "Unable to get issuer name\n");
        goto end;
    }
    BIO_printf(bio_out, "\nIssuer: %s\n", issuerName);

    sn = SSLCERT_get_subject_name(sslcert);
    subjectName = SSLCERT_NAME_oneline(sn,buf,CERT_NAME_BUF_LEN);
    if (subjectName == NULL)
    {
        BIO_printf(bio_err, "Unable to get subject name\n");
        goto end;
    }
    BIO_printf(bio_out, "\nSubject: %s\n", subjectName);

    /* Convert the R_PKEY */
    ret = R_PKEY_to_binary(rpkey,0, NULL, (unsigned int *)&key_length);
    if (ret!=R_ERROR_NONE)
    {
        goto end;
    }

    key_buffer = (unsigned char *)Malloc(key_length);
    if (key_buffer==NULL)
    {
        ret = R_ERROR_ALLOC_FAILURE;
        goto end;
    }

    key_bufptr = key_buffer;
    ret = R_PKEY_to_binary(rpkey, consumed_len, key_buffer,
                           (unsigned int *)&key_length);
    if (ret!=R_ERROR_NONE)
    {
        goto end;
    }

    if (SSLCERT_PKEY_from_binary(EVP_PKEY_RSA, &pkey, &key_buffer,
            key_length) == NULL)
    {
        BIO_printf(bio_out, "%s: unable to load private key\n",
                "SSLCERT_PKEY_from_binary");
        ERR_print_errors(bio_err);
        goto end;
    }

    BIO_printf(bio_out,"Converted SSLCERT_PKEY_from_binary\n");

    /* Check the private key against the certificate */
    if (!SSLCERT_check_private_key(sslcert, pkey ))
    {
        BIO_printf(bio_err, "Private key check failed\n");
        goto end;
    }
    else
    {
        BIO_printf(bio_out, "Private key check PASSED - SSLCERT\n");
    }


    /* 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);
    }

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

    if (cert_bufptr)
    {
        Free(cert_bufptr);
    }

    if (key_bufptr)
    {
        Free(key_bufptr);
    }

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

    if (sslcert != NULL)
    {
        SSLCERT_free(sslcert);
    }

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

    if (rcert != NULL)
    {
        R_CERT_free(rcert);
    }

    if (cert_ctx != NULL)
    {
       R_CERT_CTX_free(cert_ctx);
    }

    if (key_ctx != NULL)
    {
       R_PKEY_CTX_free(key_ctx);
    }

    /* Free the SSL library context */
    if (lib_ctx != NULL)
    {
        PRODUCT_LIBRARY_FREE(lib_ctx);
    }

    if (bio_err != NULL)
    {
        BIO_free(bio_err);
        bio_err = NULL;
    }

    return(R_ERROR_EXIT_CODE(ret));
}


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