diff -r 000000000000 -r ba25891c3a9e secureswitools/swisistools/source/signsislib/siscertificatechain.cpp --- /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 +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#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 (aBlob.Data ()); + unsigned char* ptr = was; + assert (ptr); + ptr += aOffset; + if (! d2i_X509 (&x509, &ptr, static_cast (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 (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 (size)); +#else + aBlob.Prepend (buffer, static_cast (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(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); + } + } + +