pkiutilities/untrustedcertificatedialog/src/untrustedcertificateinfo_symbian.cpp
author hgs
Thu, 07 Oct 2010 14:07:34 +0300
changeset 62 3255e7d5bd67
parent 30 cc1cea6aabaf
permissions -rw-r--r--
201037_06

/*
* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of "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: Certificate info class for TLS untrusted certificate dialog.
*
*/

#include "untrustedcertificateinfo_symbian.h"
#include <signed.h>                             // TAlgorithmId
#include <x509cert.h>                           // CX509Certificate
#include <X509CertNameParser.h>                 // X509CertNameParser
#include <hash.h>                               // CMD5


// ======== LOCAL FUNCTIONS ========

// ----------------------------------------------------------------------------
// mapAlgorithm()
// ----------------------------------------------------------------------------
//
UntrustedCertificateInfoBase::Algorithm mapAlgorithm(TAlgorithmId aAlgId)
{
    UntrustedCertificateInfoBase::Algorithm algorithm =
        UntrustedCertificateInfoBase::Unknown;
    switch(aAlgId) {
        case ERSA:
            algorithm = UntrustedCertificateInfoBase::RSA;
            break;
        case EDSA:
            algorithm = UntrustedCertificateInfoBase::DSA;
            break;
        case EDH:
            algorithm = UntrustedCertificateInfoBase::DH;
            break;
        case EMD2:
            algorithm = UntrustedCertificateInfoBase::MD2;
            break;
        case EMD5:
            algorithm = UntrustedCertificateInfoBase::MD5;
            break;
        case ESHA1:
            algorithm = UntrustedCertificateInfoBase::SHA1;
            break;
        case ESHA224:
            algorithm = UntrustedCertificateInfoBase::SHA224;
            break;
        case ESHA256:
            algorithm = UntrustedCertificateInfoBase::SHA256;
            break;
        case ESHA384:
            algorithm = UntrustedCertificateInfoBase::SHA384;
            break;
        case ESHA512:
            algorithm = UntrustedCertificateInfoBase::SHA512;
            break;
        default:
            break;
    }
    return algorithm;
}

// ----------------------------------------------------------------------------
// convertDateTime()
// ----------------------------------------------------------------------------
//
void convertDateTime(const TTime& aFromTime, QDateTime& aToDateTime)
{
    const TDateTime &symbianDateTime = aFromTime.DateTime();

    QDate date(symbianDateTime.Year(), symbianDateTime.Month()+1, symbianDateTime.Day()+1);
    QTime time(symbianDateTime.Hour(), symbianDateTime.Minute(), symbianDateTime.Second());
    aToDateTime.setDate(date);
    aToDateTime.setTime(time);
}


// ======== MEMBER FUNCTIONS ========

// ----------------------------------------------------------------------------
// UntrustedCertificateInfoSymbian::UntrustedCertificateInfoSymbian()
// ----------------------------------------------------------------------------
//
UntrustedCertificateInfoSymbian::UntrustedCertificateInfoSymbian(
    const QByteArray &aEncodedCert) : UntrustedCertificateInfoBase(),
    mCert(0), mMd5Fingerprint()
{
    QT_TRAP_THROWING(ConstructL(aEncodedCert));
}

// ----------------------------------------------------------------------------
// UntrustedCertificateInfoSymbian::~UntrustedCertificateInfoSymbian()
// ----------------------------------------------------------------------------
//
UntrustedCertificateInfoSymbian::~UntrustedCertificateInfoSymbian()
{
    delete mCert;
}

// ----------------------------------------------------------------------------
// UntrustedCertificateInfoSymbian::commonNameMatches()
// ----------------------------------------------------------------------------
//
bool UntrustedCertificateInfoSymbian::commonNameMatches(const QString &siteName) const
{
    bool matches = false;
    QT_TRAP_THROWING(matches = CommonNameMatchesL(siteName));
    return matches;
}

// ----------------------------------------------------------------------------
// UntrustedCertificateInfoSymbian::certificateDetails()
// ----------------------------------------------------------------------------
//
QString UntrustedCertificateInfoSymbian::certificateDetails(const QString &siteName) const
{
    // TODO: localized UI string needed
    QString details = tr("Service:\n%1\n\nIssuer:\n%2\n\nSubject:\n%3\n\n"
        "Valid from:\n%4\n\nValid until:\n%5\n\nCertificate format:\n%6\n\n"
        "Algorithm:\n%7\n\nSerial number:\n%8\n\n"
        "Fingerprint (SHA1):\n%9\n\nFingerprint (MD5):\n%10")
        .arg(siteName)                                  // %1
        .arg(issuerName())                              // %2
        .arg(subjectName())                             // %3
        .arg(validFrom().toString())                    // %4
        .arg(validTo().toString())                      // %5
        .arg(format())                                  // %6
        .arg(combinedAlgorithmName())                   // %7
        .arg(formattedSerialNumber(serialNumber()))     // %8
        .arg(formattedFingerprint(fingerprint()))       // %9
        .arg(formattedFingerprint(mMd5Fingerprint));    // %10
    return details;
}

// ----------------------------------------------------------------------------
// UntrustedCertificateInfoSymbian::ConstructL()
// ----------------------------------------------------------------------------
//
void UntrustedCertificateInfoSymbian::ConstructL(const QByteArray &aEncodedCert)
{
    TPtrC8 encodedCert( reinterpret_cast<const TText8*>( aEncodedCert.constData() ),
        aEncodedCert.length() );

    ASSERT( mCert == 0 );
    mCert = CX509Certificate::NewL( encodedCert );

    HBufC16* subjectBuf = NULL;
    X509CertNameParser::SubjectFullNameL( *mCert, subjectBuf );
    CleanupStack::PushL( subjectBuf );
    QT_TRYCATCH_LEAVING( mSubjectName =
        QString::fromUtf16(subjectBuf->Ptr(), subjectBuf->Length()) );
    CleanupStack::PopAndDestroy( subjectBuf );

    HBufC16* issuerBuf = NULL;
    X509CertNameParser::IssuerFullNameL( *mCert, issuerBuf );
    CleanupStack::PushL( issuerBuf );
    QT_TRYCATCH_LEAVING( mIssuerName =
        QString::fromUtf16(issuerBuf->Ptr(), issuerBuf->Length()));
    CleanupStack::PopAndDestroy( issuerBuf );

    TPtrC8 fingerprint = mCert->Fingerprint();
    QT_TRYCATCH_LEAVING( mFingerprint = QByteArray::fromRawData(
        reinterpret_cast<const char*>(fingerprint.Ptr()), fingerprint.Length()) );

    mMd5Fingerprint = Md5FingerprintL( mCert->Encoding() );

    TPtrC8 serialNumber = mCert->SerialNumber();
    QT_TRYCATCH_LEAVING( mSerialNumber = QByteArray::fromRawData(
        reinterpret_cast<const char*>(serialNumber.Ptr()), serialNumber.Length()) );

    const CValidityPeriod& validityPeriod = mCert->ValidityPeriod();
    convertDateTime(validityPeriod.Start(), mValidFrom);
    convertDateTime(validityPeriod.Finish(), mValidTo);

    mFormat = X509Certificate;

    const CSigningAlgorithmIdentifier& alg = mCert->SigningAlgorithm();
    mDigestAlgorithm = mapAlgorithm(alg.DigestAlgorithm().Algorithm());
    mAsymmetricAlgorithm = mapAlgorithm(alg.AsymmetricAlgorithm().Algorithm());
}

// ----------------------------------------------------------------------------
// UntrustedCertificateInfoSymbian::CommonNameMatchesL()
// ----------------------------------------------------------------------------
//
bool UntrustedCertificateInfoSymbian::CommonNameMatchesL(const QString &siteName) const
{
    bool matches = false;
    const CX500DistinguishedName& distinguishedName = mCert->SubjectName();
    HBufC* commonNameSymbian = distinguishedName.ExtractFieldL( KX520CommonName );
    if (commonNameSymbian) {
        CleanupStack::PushL(commonNameSymbian);
        QString commonName = QString::fromRawData(
            reinterpret_cast<const QChar*>(commonNameSymbian->Ptr()),
            commonNameSymbian->Length());
        matches = ( commonName == siteName );       // TODO: accept '*' chars in commonName?
        CleanupStack::PopAndDestroy(commonNameSymbian);
    }
    return matches;
}

// ----------------------------------------------------------------------------
// UntrustedCertificateInfoSymbian::Md5FingerprintL()
// ----------------------------------------------------------------------------
//
QByteArray UntrustedCertificateInfoSymbian::Md5FingerprintL( const TDesC8& aEncodedCert ) const
{
    CMD5* md5 = CMD5::NewL();
    CleanupStack::PushL( md5 );

    const TPtrC8 fingerprintSymbian = md5->Hash( aEncodedCert );
    QByteArray fingerprint( reinterpret_cast<const char*>( fingerprintSymbian.Ptr() ),
        fingerprintSymbian.Length() );

    CleanupStack::PopAndDestroy( md5 );
    return fingerprint;
}