diff -r 000000000000 -r ba25891c3a9e secureswitools/makekeys/src/CertificateRequestGenerator.cpp --- /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; jvalue->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; + }