secureswitools/makekeys/src/CertificateRequestGenerator.cpp
changeset 0 ba25891c3a9e
equal deleted inserted replaced
-1:000000000000 0:ba25891c3a9e
       
     1 /*
       
     2 * Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of the License "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: 
       
    15 * Implementation of the CCertificateRequestGenerator class
       
    16 * INCLUDES
       
    17 *
       
    18 */
       
    19 
       
    20 
       
    21 #include "CertificateRequestGenerator.h"
       
    22 
       
    23 
       
    24 // ===========================================================================
       
    25 // Construction/Destruction
       
    26 // ===========================================================================
       
    27 
       
    28 CCertificateRequestGenerator::CCertificateRequestGenerator()
       
    29 	{
       
    30 	memset(m_RequestFile, 0, MAXLEN);
       
    31 	}
       
    32 
       
    33 CCertificateRequestGenerator::CCertificateRequestGenerator(_TCHAR* aDnPtr)
       
    34 	{
       
    35 	}
       
    36 
       
    37 CCertificateRequestGenerator::~CCertificateRequestGenerator()
       
    38 	{
       
    39 	}
       
    40 
       
    41 void CCertificateRequestGenerator::SetRequestName(_TCHAR* aStr)
       
    42 	{
       
    43 	if(aStr != NULL)
       
    44 		{
       
    45 		_tcscpy(m_RequestFile, aStr);
       
    46 		}
       
    47 	}
       
    48 
       
    49 int CCertificateRequestGenerator::Generate()
       
    50 //Generate certificate request and write into a file
       
    51 	{
       
    52 	FILE*		  fp			= NULL;
       
    53 	char*		  pbPassword	= NULL;
       
    54 	EVP_PKEY* 	  pKey			= NULL;
       
    55 	X509_REQ*	  pReq			= NULL;
       
    56 	X509_NAME*	  pSubj			= NULL;
       
    57 	const EVP_MD* pDigest		= NULL;
       
    58 	DWORD		  bytesWritten;
       
    59 	struct entry_pack* pEntPack = NULL;
       
    60 
       
    61 	int retFunc	= FAIL;
       
    62 
       
    63 	//Get command prompt handle
       
    64 	HANDLE hndl = GetStdHandle(STD_OUTPUT_HANDLE);
       
    65 	
       
    66 	OPENSSL_add_all_algorithms_conf();
       
    67 	ERR_load_crypto_strings();
       
    68 
       
    69 	//First read private key from key file
       
    70 	if(!(fp = _tfopen(m_privateKeyFile, _T("r"))))
       
    71 		{
       
    72 		PrintErrorInfo("Error reading key file!", EGeneric, constparams);
       
    73 		WriteConsole(hndl, m_privateKeyFile, wcslen(m_privateKeyFile), &bytesWritten, 0);
       
    74 		return retFunc;
       
    75 		}
       
    76 
       
    77 	if(m_password[0] != 0)
       
    78 		{
       
    79 		DWORD len = 0;
       
    80 		len = _tcslen(m_password);
       
    81 		pbPassword = MakeMBCSString(m_password, CP_UTF8, len);
       
    82 		pKey = PEM_read_PrivateKey(fp, NULL, NULL, pbPassword);
       
    83 		delete pbPassword;
       
    84 		}
       
    85 	else
       
    86 		{
       
    87 		pKey = PEM_read_PrivateKey(fp, NULL, NULL, NULL);
       
    88 		}
       
    89 			
       
    90 	fclose(fp); fp = NULL;
       
    91 
       
    92 	if(!pKey)
       
    93 		{
       
    94 		PrintErrorInfo("Error reading private key in key file!", EOPENSSL, constparams);
       
    95 		return retFunc;
       
    96 		}
       
    97 	try
       
    98 		{
       
    99 		//Create a new cert request and add the public key into it
       
   100 		if(!(pReq = X509_REQ_new()))
       
   101 			{
       
   102 			PrintErrorInfo("Error creating X509 request object!", EOPENSSL, constparams);
       
   103 			throw EOPENSSL;
       
   104 			}
       
   105 
       
   106 		X509_REQ_set_pubkey(pReq, pKey);
       
   107 
       
   108 		//Now create DN name entries and assign them to request
       
   109 		if(!(pSubj = X509_NAME_new()))
       
   110 			{
       
   111 			PrintErrorInfo("Error creating X509 name object!", EOPENSSL, constparams);
       
   112 			throw EOPENSSL;
       
   113 			}
       
   114 
       
   115 		//Format DN string
       
   116 		DoFormatted(m_dname, &pEntPack);
       
   117 
       
   118 		if(pEntPack->num == 0)
       
   119 			{
       
   120 			PrintErrorInfo("Error formatting Distinguished Name!", EGeneric, constparams);
       
   121 			throw EGeneric;
       
   122 			}
       
   123 
       
   124 		for (int i = 0; i < pEntPack->num; i++)
       
   125 			{
       
   126 			int nid = 0;
       
   127 			DWORD lent = 0;
       
   128 			X509_NAME_ENTRY *pEnt = NULL;
       
   129 			LPSTR pbMBSTRUTF8 = NULL;
       
   130 
       
   131 			if((pEntPack->entries[i].value == NULL) || (pEntPack->entries[i].key == NULL))
       
   132 				{
       
   133 				PrintErrorInfo("Error in Distinguished Name construction!", EGeneric, constparams);
       
   134 				throw EGeneric;
       
   135 				}
       
   136 
       
   137 			if((nid = OBJ_txt2nid(pEntPack->entries[i].key)) == NID_undef)
       
   138 				{
       
   139 				PrintErrorInfo("Error finding NID for a DN entry!", EOPENSSL, constparams);
       
   140 				throw EOPENSSL;
       
   141 				}
       
   142 			lent = _tcslen(pEntPack->entries[i].value);
       
   143 			pbMBSTRUTF8 = MakeMBCSString(pEntPack->entries[i].value, CP_UTF8, lent);
       
   144 
       
   145 			if(lent > 64) //OpenSSL does not accept a string longer than 64 
       
   146 				{
       
   147 				if(!(pEnt = X509_NAME_ENTRY_create_by_NID(NULL, nid, MBSTRING_UTF8, (unsigned char *)"dummy", 5)))
       
   148 					{
       
   149 					PrintErrorInfo("Error creating name entry from NID!", EOPENSSL, constparams);
       
   150 					throw EOPENSSL;
       
   151 					}
       
   152 				
       
   153 				pEnt->value->data = (unsigned char *)malloc(lent+1);
       
   154 				
       
   155 				for(DWORD j=0; j<lent; j++ )
       
   156 					{
       
   157 					pEnt->value->data[j] = pbMBSTRUTF8[j];
       
   158 					}
       
   159 				
       
   160 				pEnt->value->length = lent;
       
   161 
       
   162 				} 
       
   163 			else if(!(pEnt = X509_NAME_ENTRY_create_by_NID(NULL, nid, MBSTRING_UTF8, (unsigned char *)pbMBSTRUTF8, lent)))
       
   164 				{
       
   165 				PrintErrorInfo("Error creating name entry from NID!", EOPENSSL, constparams);
       
   166 				throw EOPENSSL;
       
   167 				}
       
   168 
       
   169 			if(X509_NAME_add_entry(pSubj, pEnt, -1, 0) != 1)
       
   170 				{
       
   171 				PrintErrorInfo("Error adding entry to X509 Name!", EOPENSSL, constparams);
       
   172 				throw EOPENSSL;
       
   173 				}
       
   174 			delete pbMBSTRUTF8;
       
   175 			}//for
       
   176 		
       
   177 		SYMBIAN_FREE_MEM(pEntPack);
       
   178 
       
   179 		if(X509_REQ_set_subject_name(pReq, pSubj) != 1)
       
   180 			{
       
   181 			PrintErrorInfo("Error adding subject to request!", EOPENSSL, constparams);
       
   182 			throw EOPENSSL;
       
   183 			}
       
   184 
       
   185 			//Find the correct digest and sign the request
       
   186 
       
   187 		if(EVP_PKEY_type(pKey->type) == EVP_PKEY_DSA)
       
   188 			{
       
   189 			pDigest = EVP_dss1();
       
   190 			}
       
   191 		else if(EVP_PKEY_type(pKey->type) == EVP_PKEY_RSA)
       
   192 			{
       
   193 			pDigest = EVP_sha1();
       
   194 			}
       
   195 		else
       
   196 			{
       
   197 			PrintErrorInfo("Error checking private key type!", EOPENSSL, constparams);
       
   198 			throw EOPENSSL;
       
   199 			}
       
   200 
       
   201 		if(!(X509_REQ_sign(pReq, pKey, pDigest)))
       
   202 			{
       
   203 			PrintErrorInfo("Error signing request!", EOPENSSL, constparams);
       
   204 			throw EOPENSSL;
       
   205 			}
       
   206 
       
   207 		if(!(fp = _tfopen(m_RequestFile, _T("w"))))
       
   208 			{
       
   209 			PrintErrorInfo("Error writing to request file!",EGeneric,constparams);
       
   210 			throw EGeneric;
       
   211 			}
       
   212 	
       
   213 		if(PEM_write_X509_REQ(fp, pReq) != 1)
       
   214 			{
       
   215 			PrintErrorInfo("Error while writing to request file!", EOPENSSL, constparams);
       
   216 			throw EOPENSSL;
       
   217 			}
       
   218 
       
   219 		//Free variables
       
   220 		EVP_PKEY_free(pKey);
       
   221 		X509_NAME_free(pSubj);
       
   222 		X509_REQ_free(pReq);
       
   223 		fclose(fp);
       
   224 
       
   225 		_tprintf(_T("\nCreated request: "));
       
   226 		WriteConsole(hndl, m_RequestFile, wcslen(m_RequestFile), &bytesWritten, 0);
       
   227 
       
   228 		retFunc = SUCCESS;
       
   229 
       
   230 		}
       
   231 	catch (...)
       
   232 		{
       
   233 		if(pKey)
       
   234 			{
       
   235 			EVP_PKEY_free(pKey);
       
   236 			}
       
   237 		
       
   238 		if(pSubj)
       
   239 			{
       
   240 			X509_NAME_free(pSubj);
       
   241 			}
       
   242 
       
   243 		if(pReq)
       
   244 			{
       
   245 			X509_REQ_free(pReq);
       
   246 			}
       
   247 
       
   248 		SYMBIAN_FREE_MEM(pEntPack);
       
   249 		}
       
   250 
       
   251 	return retFunc;
       
   252 	}