secureswitools/swisistools/source/signsislib/siscertificatechain.cpp
changeset 0 ba25891c3a9e
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/secureswitools/swisistools/source/signsislib/siscertificatechain.cpp	Thu Dec 17 08:51:10 2009 +0200
@@ -0,0 +1,306 @@
+/*
+* Copyright (c) 2004-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: 
+*
+*/
+
+
+/**
+ @file 
+ @internalComponent
+ @released
+*/
+
+
+#include <iostream>
+#include <fstream>
+#include <string>
+#include <iomanip>
+
+#include <openssl/rsa.h>
+#include <openssl/dsa.h>
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/x509v3.h>
+#include <openssl/sha.h>
+#include <openssl/pem.h>
+#include <openssl/x509.h>
+#include <openssl/err.h>
+#include <openssl/pem.h>
+#include <openssl/evp.h>
+#include <openssl/err.h>
+#include <openssl/ssl.h>
+#include <openssl/bio.h>
+
+
+#include "utility_interface.h"
+#include "siscertificatechain.h"
+#include "certchaindata.h"
+#include "exception.h"
+#include "utility.h"
+#include "certificateinfo.h"
+
+
+CSisCertificateChain::CSisCertificateChain (CCertChainData& aSisCertChain): iSisCertChain(aSisCertChain) 
+	{
+	ConstructL();
+	}
+
+void CSisCertificateChain::ConstructL()
+	{
+	CSISFieldRoot::TFieldSize offset = 0;
+	X509* x509 = GetX509 (offset);
+
+	while(x509 != NULL)
+		{
+		CCertificateInfo* certInfo = new CCertificateInfo(x509);
+		iCertificateList.push_back(certInfo);
+		x509 = GetX509 (offset);
+		}
+	}
+
+CSisCertificateChain::~CSisCertificateChain()
+	{
+	for(int i = 0; i < iCertificateList.size(); ++i)
+		{
+		delete iCertificateList[i];
+		}
+	iCertificateList.clear();
+	}
+
+X509* BlobToX509 (const CSISBlob& aBlob, CSISFieldRoot::TFieldSize& aOffset)
+	{
+	assert (aBlob.Size ());
+	assert (aBlob.Size () < 0X7FFFFFFF);	// openssl limits
+	X509* x509 = NULL;
+	unsigned char* was = const_cast <unsigned char*> (aBlob.Data ());
+	unsigned char* ptr = was;
+	assert (ptr);
+	ptr += aOffset;
+	if (! d2i_X509 (&x509, &ptr, static_cast <int> (aBlob.Size ())))
+		{
+		throw CSISException (CSISException::ECrypto, "invalid certificate chain");
+		}
+	aOffset = (ptr - was);
+	assert (x509);
+	return x509;
+	}
+
+void X509ToBlob (CSISBlob& aBlob, X509* aX509)
+	{
+	TUint8* buffer = NULL;
+	int size = i2d_X509 (aX509, &buffer);
+	if ((size <= 0) || (buffer == NULL))
+		{
+		throw CSISException (CSISException::ECrypto, "invalid X509");
+		}
+	try
+		{
+		aBlob.Assign (buffer, static_cast <CSISFieldRoot::TFieldSize> (size));
+		}
+	catch (...)
+		{
+		OPENSSL_free (buffer);
+		throw;
+		}
+	OPENSSL_free (buffer);
+	}
+
+
+void X509ToBlobAppend (CSISBlob& aBlob, X509* aX509)
+	{
+	TUint8* buffer = NULL;
+	int size = i2d_X509 (aX509, &buffer);
+	if ((size <= 0) || (buffer == NULL))
+		{
+		throw CSISException (CSISException::ECrypto, "invalid X509");
+		}
+	try
+		{
+
+#ifndef X509_CHAIN_ORDER_ROOT_FIRST
+		aBlob.Append (buffer, static_cast <CSISFieldRoot::TFieldSize> (size));
+#else
+		aBlob.Prepend (buffer, static_cast <CSISFieldRoot::TFieldSize> (size));
+#endif /* X509_CHAIN_ORDER_ROOT_FIRST */
+
+		}
+	catch (...)
+		{
+		OPENSSL_free (buffer);
+		throw;
+		}
+	OPENSSL_free (buffer);
+	}
+
+void CSisCertificateChain::LoadText (const std::wstring& aName)
+	{	
+		char *fName = NULL;	
+		std::ifstream certFile;
+		std::string line;
+		std::string buffer;
+
+		certFile.rdbuf()->open(wstring2string (aName).c_str (), std::ios::in);
+
+		if (!certFile.is_open())
+			{
+			if((fName = Copy2TmpFile(aName.c_str(), CERTFILE)) != NULL)
+				{
+				certFile.rdbuf()->open(fName, std::ios::in);
+				}
+			}
+		
+		//check if file is successfully opened.
+		if(certFile.is_open())
+			{
+			//reads the file (pem certificate) into the buffer ignoring empty lines.
+			while(!certFile.eof())
+				{
+				getline(certFile,line);
+				//ignore blank lines.
+				if(line.length())
+					{
+					buffer.append(line);
+					buffer.append("\n");
+					}
+				}
+			
+			certFile.rdbuf()->close();
+			}
+		
+		else
+			{
+			CSISException::ThrowIf (1, CSISException::EFileProblem, std::wstring (L"cannot open ") + aName);
+			}
+
+		if(fName != NULL)
+		{
+			DeleteFileA(fName);
+			delete fName;
+		}
+		
+		X509* x509 = NULL;
+		BIO* mem = NULL;
+		
+		try
+			{
+			ERR_clear_error();
+			//creates a memory BIO and writes the buffer data into it.
+			mem = BIO_new(BIO_s_mem());
+			BIO_puts(mem , buffer.c_str());
+			while(PEM_read_bio_X509 (mem , &x509 ,0 ,NULL) != NULL)
+				{
+				X509ToBlobAppend (const_cast<CSISBlob&>(iSisCertChain.CertificateData()), x509);
+				X509_free (x509);
+				x509 = NULL;
+				}
+			BIO_free(mem); mem = NULL;
+			if(iSisCertChain.CertificateData().Size() == 0)
+				throw 0;
+			}
+		
+		catch (...)
+			{
+
+			if (certFile.rdbuf()->is_open())
+			{
+			certFile.rdbuf()->close();
+			}
+			
+			if (x509)
+				{
+				X509_free (x509);
+				}
+			
+			if(mem)
+				{
+				BIO_free(mem);
+				}
+			
+			iSisCertChain.CertificateData().Dispose ();
+			throw CSISException (CSISException::ECrypto, std::wstring (L"Cannot read ") + aName);
+			}
+	
+	}
+
+
+
+void CSisCertificateChain::LoadBinary (const std::wstring& aName)
+
+	{
+	try
+		{
+		iSisCertChain.CertificateData().Load (aName);
+		}
+	catch (...)
+		{
+		throw CSISException (CSISException::ECrypto, aName + std::wstring (L" is invalid"));
+		}
+	}
+
+
+
+void CSisCertificateChain::Load (const std::wstring& aName)
+	{
+	try
+		{
+		LoadText (aName);
+		return;
+		}
+	catch (...)
+		{
+		try
+			{
+			LoadBinary (aName);
+			return;
+			}
+		catch (...)
+			{
+			}
+		throw;
+		}
+	}
+
+
+X509* CSisCertificateChain::GetX509 (CSISFieldRoot::TFieldSize& aOffset) const
+	{
+	if (aOffset >= iSisCertChain.CertificateData().Size ())
+		{
+		return NULL;
+		}
+
+	return BlobToX509 (iSisCertChain.CertificateData(), aOffset);
+	}
+
+
+X509* CSisCertificateChain::GetBottomX509 () const
+	{
+	CSISFieldRoot::TFieldSize offset = 0;
+	X509* reply = GetX509(offset);
+	return reply;
+	}
+
+
+void CSisCertificateChain::ExtractCertificateChain (std::string& aCertFileName)
+{
+	ERR_clear_error();
+	CSISFieldRoot::TFieldSize offset = 0;
+
+	for(int i = 0; i < iCertificateList.size(); ++i)
+		{
+		iCertificateList[i]->ExtractCertificate(aCertFileName);
+		}
+	}
+
+