dear all
i have a client server client application the server should created an
encrypted shared key and some data and make digest of both of them (data
and encrypted shared key) as an input to SHA1 then the server should sign
the output of the hash with function SignDigest() which include function
RSA_sign to sign the digest
my problem is
1- the code give an error No source available for "RSA_sign() at
0xb7ea85e5"

2- i have tried to know what is the error so i added
error = ERR_get_error();

but i got nothing can you tell me what i did wrong

thanks allot for your reply

-- 
Warmest regards and best wishes for a good health,*urs sincerely *
*mero*
//============================================================================
// Name        : certificate.cpp
// Author      : Amir
// Version     :
// Copyright   : Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================

#include <iostream>
#include "server.h"
#include "client.h"
using namespace std;

int main()
{
	clock_t start, end;
	double msecs;

	start = clock();

	Client clientest;
    Server servertest;

    X509 *cert;
    cert = servertest.CreateCertificate(clientest.MakeSignedCertReq());

    clientest.SetCert(cert);
    clientest.CertConverter();
    X509 *test;
    test = clientest.GetCert();
    servertest.CheckCert(cert);
    int serial = 0;
    serial = clientest.ExtractCertSerial();
    cout<<"client serial is "<<serial<<endl;

    servertest.SetSharedKey();
    servertest.EncryptSharedKey(cert);

    unsigned char enckey[RSA_KEY_SIZE];
    servertest.GetEncryptedKey(enckey,RSA_KEY_SIZE);

    clientest.DecryptSharedKey(enckey);

    servertest.SetData(DATA_SIZE);
    servertest.SetDigestData();
    servertest.CreateDigest();
    servertest.SignDigest();

	end = clock();
	msecs = ((double) (end - start)) * 1000 / CLOCKS_PER_SEC;
	cout<<"time is "<<msecs<<"msec"<<endl;

	return 0;
}
/*
 * client.cc
 *
 *  Created on: Sep 17, 2014
 *      Author: amirale32
 */

#include "client.h"

 Client :: Client()
 {
	  m_myCertReq = X509_REQ_new();
	  m_myCert = X509_new();
	  m_name = X509_NAME_new();
	  m_rsa_keyPair = RSA_new();
	  m_puk  = EVP_PKEY_new();
	  GenerateRSAKeyPair();
 }

 Client :: ~Client()
 {
	  X509_REQ_free(m_myCertReq);
	  X509_free(m_myCert);
	  RSA_free(m_rsa_keyPair);
 }

 void
 Client :: GenerateRSAKeyPair ( )
 {
     m_rsa_keyPair = RSA_generate_key((8*RSA_KEY_SIZE),RSA_F4,NULL,NULL);
     BIO *pubout = NULL;
     const char szPath[MAX_FILE_NAME_SIZE] = "clrsa.pem";
     pubout = BIO_new_file(szPath,"wb");
     PEM_write_bio_RSAPublicKey (pubout , m_rsa_keyPair);
     BIO_free(pubout);

}

 void
 Client::SetPublicKey()
 {
	 EVP_PKEY_assign_RSA(m_puk,m_rsa_keyPair);
     BIO *out = NULL;
     const char szPath[MAX_FILE_NAME_SIZE] = "cpuky.pem";
     out = BIO_new_file(szPath,"wb");
     PEM_write_bio_PUBKEY(out,m_puk);
 }

 X509_REQ*
 Client::MakeSignedCertReq()
 {
	 //adds all digest algorithms to the table
	 OpenSSL_add_all_digests();
	 SetPublicKey();
	 //include the public key in the req
	 X509_REQ_set_pubkey(m_myCertReq,m_puk);
	 //set the subject name of the request
	 m_name=X509_REQ_get_subject_name(m_myCertReq);
	 //set the request
	 X509_NAME_add_entry_by_txt(m_name,"C",MBSTRING_ASC, (const unsigned char *)"UK", -1, -1, 0);
	 X509_NAME_add_entry_by_txt(m_name,"CN",MBSTRING_ASC, (const unsigned char *)"OpenSSL Group", -1, -1, 0);
	 //sign the req
	 X509_REQ_sign(m_myCertReq,m_puk,EVP_sha1());
	 BIO *out = NULL;
	 const char szPath[MAX_FILE_NAME_SIZE] = "req.pem";
	 out = BIO_new_file(szPath,"wb");
	 PEM_write_bio_X509_REQ(out,m_myCertReq);
	 BIO_free(out);
	 return m_myCertReq;
}

 void
 Client::SetCert(X509 *cert)
 {
	 m_myCert =  cert;
	 BIO *out = NULL;
	 const char szPath[MAX_FILE_NAME_SIZE] = "clcrt.pem";
	 out = BIO_new_file(szPath,"wb");
	 PEM_write_bio_X509 (out , cert);
}

 int
 Client::CertConverter()
 {
	 int len = i2d_X509(m_myCert, NULL);
	 unsigned char *buf, *p;
	 buf = (unsigned char *)OPENSSL_malloc(len);
	 p = buf;
	 i2d_X509(m_myCert, &p);
	 unsigned char certarray[len];
	 for (int i = 0 ; i<len ; i++)
	 {
		 certarray[i] = *(p-len+i);
	 }
	 cout<<"cert len is "<<len<<endl;
	 cout << "converted client cert is"<<endl;
	 for (int j = 0 ; j<len ; j++)
	 {
	     	printf("0x%.2x ", certarray[j]);
	 }
	 cout<<endl;

	 X509 *certtest;
	 unsigned char *buf1;
	 buf1 = certarray;
	 const unsigned char *p1 = buf1;
	 p1 = buf1;
	 certtest = d2i_X509(NULL, &p1, CERT_SIZE);

	 FILE * fcert;
	 fcert = fopen("certarray.pem", "wb");
	 PEM_write_X509(
	     fcert,    //write the certificate to the file we've opened
	     certtest  //our certificate
	 );
	 return 0;
}

 X509*
 Client::GetCert()
 {
	 return m_myCert;
}

 int
 Client::ExtractCertSerial()
 {
	 int serial = 0;
	 unsigned char **out = NULL;
	 ASN1_INTEGER *asn1_serial = NULL;

	 asn1_serial = X509_get_serialNumber(m_myCert);
	 serial = i2d_ASN1_INTEGER(asn1_serial, out);
	 return (serial);
}

void
Client::DecryptSharedKey(unsigned char encryptedkey[])
{
	int padding = RSA_PKCS1_PADDING;
    RSA_private_decrypt(RSA_KEY_SIZE,encryptedkey,m_DecryptedSharedKey,m_rsa_keyPair,padding);

    cout<<" shared key after decryption is "<<endl;
    for (int i = 0 ; i<SHARED_KEY_SIZE ; i++)
    {
    	printf("0x%.2x ", m_DecryptedSharedKey[i]);
    }
    cout<<endl;
}
 /*
void
Client::SignData()
{
	int padding = RSA_PKCS1_PADDING;
	RSA_private_encrypt(DATA_SIZE, m_Data, m_signedData, m_rsa_keyPair , padding);
    cout<<"sign data is "<<endl;

    for (int i = 0 ; i <RSA_KEY_SIZE;i++)
    {
    	printf("0x%.2x ", m_signedData[i]);
    }
    cout<<endl;
}
*/
/*
 * client.h
 *
 *  Created on: Sep 17, 2014
 *      Author: amirale32
 */

#ifndef CLIENT_H_
#define CLIENT_H_

#define MAX_FILE_NAME_SIZE 20
#define RSA_KEY_SIZE 256 //bytes
#define CERT_SIZE 727
#define SHARED_KEY_SIZE 32 //bytes
#define DATA_SIZE    13
#define SIGNED_DATA_SIZE 20

#include <stdlib.h>
#include <stdio.h>
#include <openssl/rsa.h>
#include <openssl/conf.h>
#include <openssl/x509.h>
#include <openssl/pem.h>
#include <openssl/sha.h>
#include "server.h"

 class Client
 {
   public:

   Client();
   ~Client();

   void GenerateRSAKeyPair ();
   void SetPublicKey ();

   X509_REQ *MakeSignedCertReq();
   void SetCert (X509 *cert);
   X509 *GetCert();
   int CertConverter ();
   int ExtractCertSerial ();

   void DecryptSharedKey (unsigned char encryptedkey []);

   private:

   X509_REQ         *m_myCertReq;
   X509             *m_myCert;
   X509_NAME        *m_name;
   RSA              *m_rsa_keyPair;
   EVP_PKEY         *m_puk;
   unsigned char     m_DecryptedSharedKey[SHARED_KEY_SIZE];
 };



#endif /* CLIENT_H_ */
#include "server.h"

 Server::Server()
 {
	  m_myCert = X509_new();
	  m_caKeyPairs = RSA_new();
	  m_pukey  = EVP_PKEY_new();
	  m_issuerName = X509_NAME_new();
	  GenerateMyKeyPairs();
	  CreateMyCertificate();
 }

 Server::~Server()
 {
	  X509_free(m_myCert);
	  RSA_free(m_caKeyPairs);
	  X509_NAME_free(m_issuerName);
 }

 X509*
 Server::CreateCertificate(X509_REQ* req)
 {
	 X509 *m_req_reply;
	 m_req_reply = X509_new();
	 X509_NAME *subject = NULL;
	 EVP_PKEY *pkey = NULL;
	 //check Request signature matches the certificate request
	 pkey = X509_REQ_get_pubkey(req);

	 ASN1_INTEGER_set(X509_get_serialNumber(m_req_reply), 2);

	 X509_gmtime_adj(X509_get_notBefore(m_req_reply), 0);
	 X509_gmtime_adj(X509_get_notAfter(m_req_reply), 31536000L);

	 X509_set_pubkey(m_req_reply, pkey);

	 X509_NAME *issuerSubject = X509_get_subject_name(m_myCert);

	 X509_set_issuer_name(m_req_reply, issuerSubject);

	 //extract the subject of the request
	 subject = X509_REQ_get_subject_name(req);
	 X509_set_subject_name(m_req_reply, subject);

	 X509_get_subject_name(m_req_reply);

	 X509_sign(m_req_reply, m_pukey, EVP_sha1());
	 return m_req_reply;
 }

 void
 Server::CreateMyCertificate()
 {
     // we use rsa pairs and assign it into evp_key
	 SetPublicKey();
	 // properties of the certificate
	 //set the serial number
	 ASN1_INTEGER_set(X509_get_serialNumber(m_myCert), 1);
	 //set the time validity
	 X509_gmtime_adj(X509_get_notBefore(m_myCert), 0);
	 X509_gmtime_adj(X509_get_notAfter(m_myCert), 31536000L);
	 //set the public key of the cert to be signed
	 X509_set_pubkey(m_myCert, m_pukey);
     //this is a self-signed certificate, we set the name of the issuer to the name of the subject
	 m_issuerName = X509_get_subject_name(m_myCert);

	 X509_NAME_add_entry_by_txt(m_issuerName, "C",  MBSTRING_ASC,
	                            (unsigned char *)"CA", -1, -1, 0);
	 X509_NAME_add_entry_by_txt(m_issuerName, "O",  MBSTRING_ASC,
	                            (unsigned char *)"MyCompany Inc.", -1, -1, 0);
	 X509_NAME_add_entry_by_txt(m_issuerName, "CN", MBSTRING_ASC,
	                            (unsigned char *)"localhost", -1, -1, 0);

     //set the issuer name
	 X509_set_issuer_name(m_myCert, m_issuerName);
	 //sign the cert
	 X509_sign(m_myCert, m_pukey, EVP_sha1());

	 FILE * fcert;
	 fcert = fopen("cacert.pem", "wb");
	 PEM_write_X509(
	     fcert,   /* write the certificate to the file we've opened */
	     m_myCert /* our certificate */
	 );
 }

 void
 Server::GenerateMyKeyPairs()
 {
	 m_caKeyPairs = RSA_generate_key((8*RSA_KEY_SIZE),RSA_F4 , NULL , NULL);
     BIO *pubout = NULL;
     const char szPath[MAX_FILE_NAME_SIZE] = "carsa.pem";
     pubout = BIO_new_file(szPath,"wb");
     PEM_write_bio_RSAPublicKey (pubout , m_caKeyPairs);
     BIO_free(pubout);
}

 void
 Server::SetPublicKey()
 {
	 EVP_PKEY_assign_RSA(m_pukey,m_caKeyPairs);

	 BIO *out = NULL;
	 const char szPath[MAX_FILE_NAME_SIZE] = "caevp.pem";
	 out = BIO_new_file(szPath,"wb");

	 EVP_PKEY_print_private(out, m_pukey,
	                                0, NULL);
	 BIO_free(out);
	 out = BIO_new_file("prkey.pem","wb");

	 PEM_write_bio_PrivateKey(
	     out,                  /* write the key to the file we've opened */
		 m_pukey,               /* our key from earlier */
	     EVP_des_ede3_cbc(), /* default cipher for encrypting the key on disk */
	     (unsigned char *)"replace_me",       /* passphrase required for decrypting the key on disk */
	     10,                 /* length of the passphrase string */
	     NULL,               /* callback for requesting a password */
	     NULL                /* data to pass to the callback */
	 );

 }

 void
 Server::SetSharedKey()
 {
 	cout<<"shared key is "<<endl;
 	for (int i = 0; i<SHARED_KEY_SIZE ; i++)
 	{
 	m_sharedKey[i] = i;
 	printf("0x%.2x ", m_sharedKey[i]);
 	}
 	cout<<endl;
 }

 void
 Server::EncryptSharedKey(X509 *clientcert)
 {
 	int padding = RSA_PKCS1_PADDING;
 	RSA *m_clrsa_keyPair = NULL;
 	EVP_PKEY *pkey = NULL;
 	pkey = X509_get_pubkey(clientcert);
 	m_clrsa_keyPair = EVP_PKEY_get1_RSA(pkey);
 	RSA_public_encrypt(SHARED_KEY_SIZE,m_sharedKey,m_encryptedSharedKey,m_clrsa_keyPair,padding);
     cout<<"encrypted shared key is "<<endl;
     for (int i = 0 ; i<RSA_KEY_SIZE ; i++)
     {
     	printf("0x%.2x ", m_encryptedSharedKey[i]);
     }
     cout<<endl;
 }

 void
 Server::GetEncryptedKey(unsigned char encryptedkey[], int size)
 {
	 for (int i = 0 ; i<size ; i++)
	 {
		 encryptedkey [i] = m_encryptedSharedKey [i];
	 }
 }


 int
 Server::CheckCert(X509* clientcert)
 {

	 int status = 0;
	 X509_STORE_CTX *ctx = X509_STORE_CTX_new();

     //store the trusted cert into ctx
	 X509_STORE *store = X509_STORE_new();
	 X509_STORE_add_cert(store, m_myCert);

     //put the trusted cert and cert then verify it
	 X509_STORE_CTX_init(ctx,store, clientcert, NULL);
	 status  = X509_verify_cert(ctx);

	 if (status == 1)
	 {
		 cout<<"verified succesfully"<<endl;
	 }
	 else
	 {
		 cout<<"verifiy fail"<<endl;
		 cout << X509_verify_cert_error_string(X509_STORE_CTX_get_error(ctx));
	 }
	 return status;
}

void
Server::SetData(int size)
{
	cout<<"data is "<<endl;
	for (int i = 0 ; i<size ; i++)
	{
		m_Data[i]=i;
    	printf("0x%.2x ", m_Data[i]);
	}
	cout<<endl;
}

void
Server::SetDigestData()
{
	 for (int i = 0; i<DATA_SIZE ; i++)
	 {
		 m_digestData[i] = m_Data[i];
	 }
	 for (int j = 0 ; j <RSA_KEY_SIZE ; j++ )
	 {
		 m_digestData[(DATA_SIZE+j)] = m_encryptedSharedKey[j];
	 }
	 cout <<"digest data is"<<endl;
	 for (int k = 0 ; k< (DATA_SIZE + RSA_KEY_SIZE ); k++)
	 {
	     	printf("0x%.2x ", m_digestData[k]);
	 }
	 cout<<endl;
}

void
Server::CreateDigest()
{
	SHA1(m_digestData, (DATA_SIZE + RSA_KEY_SIZE), m_digest);

	cout<<"digest is "<<endl;
	for (int i = 0; i < DIGEST_SIZE; i++)
	{
     	printf("0x%.2x ", m_digest[i]);
	}
	cout<<endl;
}

void
Server::SignDigest()
{
	  OpenSSL_add_all_ciphers();
	  OpenSSL_add_all_digests();

	cout<<"i'm in sign digest"<<endl;
	unsigned int *siglen = NULL;
	unsigned long error;
	RSA_sign(NID_sha1,m_digest, DIGEST_SIZE,m_signedDigest,siglen,m_caKeyPairs);
	error = ERR_get_error();
	cout<<"error is "<<error<<endl;

	cout <<"sig len is "<<siglen<<endl;
	cout<<"signed digest is "<<endl;
	for (int i = 0; i < RSA_KEY_SIZE; i++)
	{
     	printf("0x%.2x ", m_signedDigest[i]);
	}
	cout<<endl;
}

/*
 * server.cc
 *
 *  Created on: Sep 17, 2014
 *      Author: amirale32
 */




/*
 * server.h
 *
 *  Created on: Sep 17, 2014
 *      Author: amirale32
 */

#ifndef SERVER_H_
#define SERVER_H_

 #include <stdlib.h>
 #include <iostream>
 #include <stdio.h>
 #include <openssl/asn1.h>
 #include <openssl/ssl.h>
 #include <openssl/rsa.h>
 #include <openssl/conf.h>
 #include <openssl/err.h>
#include  "client.h"
#include <openssl/x509.h>
#include <openssl/x509_vfy.h>

#define MAX_FILE_NAME_SIZE 20
#define RSA_KEY_SIZE 256 //bytes
#define CERT_SIZE 727
#define DIGEST_SIZE 20
#define DATA_SIZE    13

using namespace std;
class Client;
 class Server
 {
 public:

	 Server();
	 ~Server();

	 X509 *CreateCertificate (X509_REQ *req);
	 void CreateMyCertificate();

	 void GenerateMyKeyPairs ( );
	 void SetPublicKey ();

	 void SetSharedKey();
	 void EncryptSharedKey(X509 *clientcert);

	 void GetEncryptedKey (unsigned char encryptedkey [],int size);

	 int CheckCert (X509 *clientcert);

	 void SetData(int size);
	 void SetDigestData();

	 void CreateDigest();

	 void SignDigest();

 private:

	 X509             *m_myCert;
	 RSA              *m_caKeyPairs;
	 EVP_PKEY         *m_pukey;
	 X509_NAME        *m_issuerName;
	 unsigned char     m_encryptedSharedKey[RSA_KEY_SIZE];
	 unsigned char     m_sharedKey[SHARED_KEY_SIZE];
	 unsigned char     m_Data[DATA_SIZE];
	 unsigned char     m_digestData[DATA_SIZE + RSA_KEY_SIZE];
	 unsigned char     m_digest[DIGEST_SIZE ];
	 unsigned char     m_signedDigest[RSA_KEY_SIZE];
 };



#endif /* SERVER_H_ */

Reply via email to