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