secureswitools/makekeys/src/CertificateRequestGenerator.cpp
changeset 0 ba25891c3a9e
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/secureswitools/makekeys/src/CertificateRequestGenerator.cpp	Thu Dec 17 08:51:10 2009 +0200
@@ -0,0 +1,252 @@
+/*
+* Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: 
+* Implementation of the CCertificateRequestGenerator class
+* INCLUDES
+*
+*/
+
+
+#include "CertificateRequestGenerator.h"
+
+
+// ===========================================================================
+// Construction/Destruction
+// ===========================================================================
+
+CCertificateRequestGenerator::CCertificateRequestGenerator()
+	{
+	memset(m_RequestFile, 0, MAXLEN);
+	}
+
+CCertificateRequestGenerator::CCertificateRequestGenerator(_TCHAR* aDnPtr)
+	{
+	}
+
+CCertificateRequestGenerator::~CCertificateRequestGenerator()
+	{
+	}
+
+void CCertificateRequestGenerator::SetRequestName(_TCHAR* aStr)
+	{
+	if(aStr != NULL)
+		{
+		_tcscpy(m_RequestFile, aStr);
+		}
+	}
+
+int CCertificateRequestGenerator::Generate()
+//Generate certificate request and write into a file
+	{
+	FILE*		  fp			= NULL;
+	char*		  pbPassword	= NULL;
+	EVP_PKEY* 	  pKey			= NULL;
+	X509_REQ*	  pReq			= NULL;
+	X509_NAME*	  pSubj			= NULL;
+	const EVP_MD* pDigest		= NULL;
+	DWORD		  bytesWritten;
+	struct entry_pack* pEntPack = NULL;
+
+	int retFunc	= FAIL;
+
+	//Get command prompt handle
+	HANDLE hndl = GetStdHandle(STD_OUTPUT_HANDLE);
+	
+	OPENSSL_add_all_algorithms_conf();
+	ERR_load_crypto_strings();
+
+	//First read private key from key file
+	if(!(fp = _tfopen(m_privateKeyFile, _T("r"))))
+		{
+		PrintErrorInfo("Error reading key file!", EGeneric, constparams);
+		WriteConsole(hndl, m_privateKeyFile, wcslen(m_privateKeyFile), &bytesWritten, 0);
+		return retFunc;
+		}
+
+	if(m_password[0] != 0)
+		{
+		DWORD len = 0;
+		len = _tcslen(m_password);
+		pbPassword = MakeMBCSString(m_password, CP_UTF8, len);
+		pKey = PEM_read_PrivateKey(fp, NULL, NULL, pbPassword);
+		delete pbPassword;
+		}
+	else
+		{
+		pKey = PEM_read_PrivateKey(fp, NULL, NULL, NULL);
+		}
+			
+	fclose(fp); fp = NULL;
+
+	if(!pKey)
+		{
+		PrintErrorInfo("Error reading private key in key file!", EOPENSSL, constparams);
+		return retFunc;
+		}
+	try
+		{
+		//Create a new cert request and add the public key into it
+		if(!(pReq = X509_REQ_new()))
+			{
+			PrintErrorInfo("Error creating X509 request object!", EOPENSSL, constparams);
+			throw EOPENSSL;
+			}
+
+		X509_REQ_set_pubkey(pReq, pKey);
+
+		//Now create DN name entries and assign them to request
+		if(!(pSubj = X509_NAME_new()))
+			{
+			PrintErrorInfo("Error creating X509 name object!", EOPENSSL, constparams);
+			throw EOPENSSL;
+			}
+
+		//Format DN string
+		DoFormatted(m_dname, &pEntPack);
+
+		if(pEntPack->num == 0)
+			{
+			PrintErrorInfo("Error formatting Distinguished Name!", EGeneric, constparams);
+			throw EGeneric;
+			}
+
+		for (int i = 0; i < pEntPack->num; i++)
+			{
+			int nid = 0;
+			DWORD lent = 0;
+			X509_NAME_ENTRY *pEnt = NULL;
+			LPSTR pbMBSTRUTF8 = NULL;
+
+			if((pEntPack->entries[i].value == NULL) || (pEntPack->entries[i].key == NULL))
+				{
+				PrintErrorInfo("Error in Distinguished Name construction!", EGeneric, constparams);
+				throw EGeneric;
+				}
+
+			if((nid = OBJ_txt2nid(pEntPack->entries[i].key)) == NID_undef)
+				{
+				PrintErrorInfo("Error finding NID for a DN entry!", EOPENSSL, constparams);
+				throw EOPENSSL;
+				}
+			lent = _tcslen(pEntPack->entries[i].value);
+			pbMBSTRUTF8 = MakeMBCSString(pEntPack->entries[i].value, CP_UTF8, lent);
+
+			if(lent > 64) //OpenSSL does not accept a string longer than 64 
+				{
+				if(!(pEnt = X509_NAME_ENTRY_create_by_NID(NULL, nid, MBSTRING_UTF8, (unsigned char *)"dummy", 5)))
+					{
+					PrintErrorInfo("Error creating name entry from NID!", EOPENSSL, constparams);
+					throw EOPENSSL;
+					}
+				
+				pEnt->value->data = (unsigned char *)malloc(lent+1);
+				
+				for(DWORD j=0; j<lent; j++ )
+					{
+					pEnt->value->data[j] = pbMBSTRUTF8[j];
+					}
+				
+				pEnt->value->length = lent;
+
+				} 
+			else if(!(pEnt = X509_NAME_ENTRY_create_by_NID(NULL, nid, MBSTRING_UTF8, (unsigned char *)pbMBSTRUTF8, lent)))
+				{
+				PrintErrorInfo("Error creating name entry from NID!", EOPENSSL, constparams);
+				throw EOPENSSL;
+				}
+
+			if(X509_NAME_add_entry(pSubj, pEnt, -1, 0) != 1)
+				{
+				PrintErrorInfo("Error adding entry to X509 Name!", EOPENSSL, constparams);
+				throw EOPENSSL;
+				}
+			delete pbMBSTRUTF8;
+			}//for
+		
+		SYMBIAN_FREE_MEM(pEntPack);
+
+		if(X509_REQ_set_subject_name(pReq, pSubj) != 1)
+			{
+			PrintErrorInfo("Error adding subject to request!", EOPENSSL, constparams);
+			throw EOPENSSL;
+			}
+
+			//Find the correct digest and sign the request
+
+		if(EVP_PKEY_type(pKey->type) == EVP_PKEY_DSA)
+			{
+			pDigest = EVP_dss1();
+			}
+		else if(EVP_PKEY_type(pKey->type) == EVP_PKEY_RSA)
+			{
+			pDigest = EVP_sha1();
+			}
+		else
+			{
+			PrintErrorInfo("Error checking private key type!", EOPENSSL, constparams);
+			throw EOPENSSL;
+			}
+
+		if(!(X509_REQ_sign(pReq, pKey, pDigest)))
+			{
+			PrintErrorInfo("Error signing request!", EOPENSSL, constparams);
+			throw EOPENSSL;
+			}
+
+		if(!(fp = _tfopen(m_RequestFile, _T("w"))))
+			{
+			PrintErrorInfo("Error writing to request file!",EGeneric,constparams);
+			throw EGeneric;
+			}
+	
+		if(PEM_write_X509_REQ(fp, pReq) != 1)
+			{
+			PrintErrorInfo("Error while writing to request file!", EOPENSSL, constparams);
+			throw EOPENSSL;
+			}
+
+		//Free variables
+		EVP_PKEY_free(pKey);
+		X509_NAME_free(pSubj);
+		X509_REQ_free(pReq);
+		fclose(fp);
+
+		_tprintf(_T("\nCreated request: "));
+		WriteConsole(hndl, m_RequestFile, wcslen(m_RequestFile), &bytesWritten, 0);
+
+		retFunc = SUCCESS;
+
+		}
+	catch (...)
+		{
+		if(pKey)
+			{
+			EVP_PKEY_free(pKey);
+			}
+		
+		if(pSubj)
+			{
+			X509_NAME_free(pSubj);
+			}
+
+		if(pReq)
+			{
+			X509_REQ_free(pReq);
+			}
+
+		SYMBIAN_FREE_MEM(pEntPack);
+		}
+
+	return retFunc;
+	}