dear all
 i made a c++ code for client server the server is the CA the client sends
a request to the CA server and the server reply by a certificate then i
have tried some options

1- server can verify the certificate using function chekcert(X509 *)
2- the client can convert the certificate into int and store it in a buffer
to be used later
3-extract the serial number of the client certificate

1- my problem is the verification of the certificate fails all the time i
don't know why
(the sign of the certificate itself failed)
2- the serial number extracted is all the time constant even if i change it
3- want make sure the function CertConverter() is working well

thx allot for help


-- 
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;

    //int serverserial = 0;
    //serverserial = servertest.ExtractCertSerial();
    //cout<<"server serial is "<<serverserial<<endl;

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

 Client :: ~Client()
 {
	  X509_REQ_free(m_myCertReq);
	  X509_free(m_myCert);
	  //X509_NAME_free(m_name);
	  RSA_free(m_rsa_keyPair);
	  //EVP_PKEY_free(m_puk);
 }

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

}

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

 X509_REQ*
 Client::MakeSignedCertReq()
 {
	 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());
	 return m_myCertReq;
}

 void
 Client::SetCert(X509 *cert)
 {
	 cout << "writing certificate\n";
	 BIO *out = NULL;
	 const char szPath[10] = "x509.pem";
	 out = BIO_new_file(szPath,"wb");
	 m_myCert =  cert;

	 int len;
	 unsigned char *buf, *p;

	 len = i2d_X509(cert, NULL);

	 cout << "cert length =" << len << endl;
     buf = (unsigned char *)OPENSSL_malloc(len);
     p = buf;
     i2d_X509(cert, &p);

     cout << "cert= "<<endl;
     for(int i=0; i<len; i++)
    	 cout << buf[i];

     cout << endl;

	 if(!PEM_write_bio_X509 (out , cert))
		 cout << "error writing certificate\n";
}

 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 << "converted client cert is"<<endl;
	 for (int j = 0 ; j<len ; j++)
	 {
		 cout << certarray[j];
	 }
	 cout<<endl;
/*
	 X509 *certtest = NULL;
	 certtest = d2i_X509(NULL, certarray , len);
	 cout<<"write the array to file"<<endl;
	 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-1);
 }
*/
/*
 * client.h
 *
 *  Created on: Sep 17, 2014
 *      Author: amirale32
 */

#ifndef CLIENT_H_
#define CLIENT_H_

#include <stdlib.h>
#include <stdio.h>
 #include <openssl/rsa.h>
 #include <openssl/conf.h>
 #include <openssl/x509.h>
 #include <openssl/pem.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 ();

   private:

   X509_REQ   *m_myCertReq;
   X509       *m_myCert;
   X509_NAME  *m_name;
   RSA        *m_rsa_keyPair;
   EVP_PKEY   *m_puk;
 };



#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();
	  //SetPublicKey();
 }

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

 X509*
 Server::CreateCertificate(X509_REQ* req)
 {
	 cout<<"hello i began"<<endl;
	 X509 *m_req_reply;
	 m_req_reply = X509_new();
	 X509_NAME *subject = NULL;
	 EVP_PKEY *pkey = NULL;

	 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);

	 pkey = X509_REQ_get_pubkey(req);
	 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);

	 cout << "cert subject name:" << X509_get_subject_name(m_req_reply) << endl;

	 {int len = i2d_X509(m_req_reply, NULL);
	 cout << "cert length =" << len << endl;}


	 {int len = i2d_X509(m_req_reply, NULL);
	 cout << "cert length =" << len << endl;}


	 if(1 == X509_sign(m_req_reply, m_pukey, EVP_sha1()))
		 cout << "client cert ok\n";
	 else
		 cout << "client cert error\n";

	 {int len = i2d_X509(m_req_reply, NULL);
	 cout << "cert length =" << len << endl;}

	 return m_req_reply;
 }

 void
 Server::CreateMyCertificate()
 {
/*
	  if (m_issuerName == NULL) cout << "error in name\n";

	  if (!X509_NAME_add_entry_by_txt(m_issuerName, "C", MBSTRING_ASC,
	                         (const unsigned char *)"UK", -1, -1, 0))
		  cout << "error in name\n";
	  if (!X509_NAME_add_entry_by_txt(m_issuerName, "O", MBSTRING_ASC,
			  (const unsigned char *)"Disorganized Organization", -1, -1, 0))
		  cout << "error in name\n";
	  if (!X509_NAME_add_entry_by_txt(m_issuerName, "CN", MBSTRING_ASC,
			  (const unsigned char *)"Joe Bloggs", -1, -1, 0))
		  cout << "error in name\n";
*/
     // 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
	 if(1 == X509_sign(m_myCert, m_pukey, EVP_sha1()))
		 cout << "self cert signed ok\n";
	 else
		 cout << "self cert sign error\n";

	 FILE * fcert;
	 fcert = fopen("cert.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(2048,RSA_F4 , NULL , NULL);
}

 void
 Server::SetPublicKey()
 {
	 if(1 == EVP_PKEY_assign_RSA(m_pukey,m_caKeyPairs))
		 cout << "key assigned OK\n";
	 else
		 cout << "key assign error\n";
	 BIO *out = NULL;
	 const char szPath[10] = "key2.pem";
	 out = BIO_new_file(szPath,"wb");

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

	 //print the self signed certificate
	 //FILE * fkey;
	 //fkey = fopen("key.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 */
	 );

 }

 int
 Server::CheckCert(X509* clientcert)
 {

	 int status = 0;
	 X509_STORE_CTX *ctx = X509_STORE_CTX_new();
	 //void X509_STORE_CTX_cleanup(X509_STORE_CTX *ctx);
	 //void X509_STORE_CTX_free(X509_STORE_CTX *ctx);

     //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);
	 //status = X509_verify(clientcert, m_pukey);

	 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;
 }
/*
 int
 Server::ExtractCertSerial()
 {
	 int serial = 0;
	 unsigned char **out;
	 ASN1_INTEGER *asn1_serial = NULL;

	 asn1_serial = X509_get_serialNumber(m_myCert);
	 serial = i2d_ASN1_INTEGER(asn1_serial, out);
	 return serial;
 }
*/
/*
 * 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  "client.h"
#include <openssl/x509.h>
#include <openssl/x509_vfy.h>

using namespace std;
 class Server
 {
 public:

	 Server();
	 ~Server();

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

	 void GenerateMyKeyPairs ( );
	 void SetPublicKey ();

	 int CheckCert (X509 *clientcert);
	 //int ExtractCertSerial ();

 private:

	 X509       *m_myCert;
	 RSA        *m_caKeyPairs;
	 EVP_PKEY   *m_pukey;
	 X509_NAME  *m_issuerName;
 };



#endif /* SERVER_H_ */

Reply via email to