Hello everybody.

My goal is to crypt/decrypt simple strings
in a programmatic way, using OpenSSL crypt library.

Please consider the C program attached below.

Could someone explain to me why on a Linux/Intel
platform this program works fine and why it doesn't
work at all on a Solaris/Sparc and even MacOS X/PowerPC
platform ?

The RSA_public_encrypt routine sends -1 as result.. why ?

Best regards

Josef
/* Test of RSA encryption */
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <openssl/rsa.h>
#include <openssl/evp.h>
#include <openssl/err.h>
#include <openssl/x509.h>
#include <openssl/pem.h>

#define NUM_ITERATIONS 1000

/***
 * Extracts public key from X.509 certificate
 */
EVP_PKEY * ReadPublicKeyInCert(const char * certfile)
{
  FILE * fp = fopen(certfile, "r");
  EVP_PKEY * pkey = NULL;
  X509 * x509;
  char ** buff = NULL;

  if (!fp) return NULL;
  x509 = (X509 *)PEM_ASN1_read((char *(*)())d2i_X509, PEM_STRING_X509,
				fp, buff, NULL, NULL);

  if (x509 == NULL) {
    ERR_print_errors_fp (stderr);
    return NULL;
  }
  fclose (fp);
  
  pkey = X509_extract_key(x509);
  X509_free(x509);
  if (pkey == NULL) ERR_print_errors_fp (stderr);
  return pkey;
}

/***
 * Reads private key from file
 */
EVP_PKEY * ReadPrivateKey(const char * keyfile)
{
  FILE * fp = fopen(keyfile, "r");
  EVP_PKEY * pkey = NULL;
  char ** buff = NULL;

  if (!fp) return NULL;
  pkey = (EVP_PKEY *)PEM_ASN1_read((char *(*)())d2i_PrivateKey, PEM_STRING_EVP_PKEY,
				   fp, buff, NULL, NULL);
  fclose (fp);
  if (pkey == NULL) ERR_print_errors_fp(stderr);
  return pkey;
}

/***
 * Main program entry
 */
int main(int argc, char * argv[]) {
  unsigned char receipt1[512], receipt2[512];
  const char * buffer = "Ceci est un message a encrypter.";
  const char * privKeyFile = "private.key";
  const char * pubKeyFile = "public.crt";
  EVP_PKEY * pubKey = NULL, * privKey = NULL;
  int enc_len = 0, dec_len = 0, i, check = 0;
  clock_t start, end, start_enc, end_enc, start_dec, end_dec;
  double elapsed = 0.0, elaps_enc = 0.0, elaps_dec = 0.0;
  unsigned long cumul_enc = 0L, cumul_dec = 0L;

  /* Start memory check */
  CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);

  /* Init of error messages */
  ERR_load_crypto_strings();

  /* Reads private key from file */
  privKey = ReadPrivateKey(privKeyFile);
  if (!privKey) {
    fprintf(stderr, "Cannot load private key in %s\n", privKeyFile);
    exit(-1);
  }

  /* Reads public key */
  pubKey = ReadPublicKeyInCert(pubKeyFile);
  if (!pubKey) {
    EVP_PKEY_free(privKey);
    fprintf(stderr, "Cannot load public key in %s\n", pubKeyFile);
    exit(-1);
  }

  memset(receipt1, '\0', sizeof(receipt1));
  memset(receipt2, '\0', sizeof(receipt2));

  printf("Original message length: %d\n", strlen(buffer));
  printf("Original message: %s\n", buffer);

  /* CPU test */
  start = clock();
  for (i = 0; i < NUM_ITERATIONS; i++) {
    /* Encryption of original text */
    start_enc = clock();
    enc_len = RSA_public_encrypt(strlen(buffer), (unsigned char *)buffer, receipt1,
				 pubKey->pkey.rsa, RSA_PKCS1_PADDING);
    if (enc_len != EVP_PKEY_size(pubKey)) {
      fprintf(stderr, "Error: ciphertext should match length of key\n");
      exit(-1);
    }
    end_enc = clock();
    cumul_enc += end_enc - start_enc;

    /* Decryption of a crypted message */
    start_dec = clock();
    dec_len = RSA_private_decrypt(strlen(receipt1), receipt1, receipt2,
				  privKey->pkey.rsa, RSA_PKCS1_PADDING);
    end_dec = clock();
    cumul_dec += end_dec - start_dec;
  }
  end = clock();

  /* Performance Stats */
  elapsed = ((double) (end - start)) / CLOCKS_PER_SEC;
  elaps_enc = (double)cumul_enc / CLOCKS_PER_SEC;
  elaps_dec = (double)cumul_dec / CLOCKS_PER_SEC;
  printf("Re-decrypted message length: %d\n", strlen(receipt2));
  printf("Decrypted message: %s\n", receipt2);
  printf("CPU time for 10000 crypt/decrypt iterations: %f seconds.\n", elapsed);
  printf("Crypt method: %.2f seconds, %.2f%% of CPU time.\n", elaps_enc, elaps_enc / elapsed * 100.0);
  printf("Decrypt method: %.2f seconds, %.2f%% of CPU time.\n", elaps_dec, elaps_dec / elapsed * 100.0);
  printf("---------------------\n");
  printf("Total: %.2f crypt/decrypt per second.\n", 10000.0 / elapsed);

  /* End of memory survey */
  CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_OFF);

  /* Free of allocated resources */
  EVP_PKEY_free(privKey);
  EVP_PKEY_free(pubKey);

  return 0;
}

Reply via email to