| RSA BSAFE Micro Edition Suite |
Streamlined security for mobile and embedded devices |
 
![]() |
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)); }