diff -r e8e63152f320 -r 2a9601315dfc javacommons/security/src.s60/ocspclient.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/javacommons/security/src.s60/ocspclient.cpp Mon May 03 12:27:20 2010 +0300 @@ -0,0 +1,368 @@ +/* +* Copyright (c) 2007-2007 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: +* +*/ + + +#include "ocspclient.h" + +using namespace java::security; +using namespace std; +using namespace java::util; + +const TInt KCertStoreUIDForSWInstallOCSPSigning = 268478646; + +OcspClient* OcspClient::createInstance(long iap, const char* defaultUrl) +{ + OcspClient* self = new OcspClient(iap); + TRAPD(err, self->ConstructL(defaultUrl)); + if (err != KErrNone) + { + delete self; + self = NULL; + } + return self; +} + +OcspClient::OcspClient(long iap) + : CActive(EPriorityNormal), iIap(TUint32(iap)), iDefaultUrl(NULL), iOcspClient(NULL), iCertStore(NULL), iInitialized(false), iOcspResponse(NULL), iCertArray(NULL), iMonitor(NULL) +{ + CActiveScheduler::Add(this); +} + +void OcspClient::ConstructL(const char* defaultUrl) +{ + User::LeaveIfError(iRfs.Connect()); + iCertStore = CUnifiedCertStore::NewL(iRfs, false /*aOpenForWrite*/); + iOcspResponse = OcspResponse::NewL(); + // create the monitor + iMonitor = Monitor::createMonitor(); + if (defaultUrl) + { + int len = strlen(defaultUrl); + iDefaultUrl = HBufC8::NewL(len); + TPtr8 defaultUrlPtr = iDefaultUrl->Des(); + TPtr8 ptr((TUint8 *)defaultUrl, len); + ptr.SetLength(len); + defaultUrlPtr.Copy(ptr); + } +} + +void OcspClient::RunL() +{ + switch (iState) + { + case ESendOcspRequest: + SendOcspRequestL(); + iState = EProcessOcspResponse; + break; + case EProcessOcspResponse: + ProcessOcspResponse(); + iMonitor->notify(); + return; + } + // re-issue a new request + SetActive(); +} + +void OcspClient::DoCancel() +{ + if (iCertStore) + { + iCertStore->CancelInitialize(); + } + if (iOcspClient) + { + iOcspClient->CancelCheck(); + } +} + +TInt OcspClient::RunError(TInt /*aError*/) +{ + return KErrNone; +} + +OcspClient::~OcspClient() +{ + if (IsActive()) + { + Cancel(); + } + if (iCertStore) + { + delete iCertStore; + iCertStore = NULL; + } + if (iOcspClient) + { + delete iOcspClient; + iOcspClient = NULL; + } + if (iOcspResponse) + { + delete iOcspResponse; + iOcspResponse = NULL; + } + if (iCertArray) + { + iCertArray->ResetAndDestroy(); + delete iCertArray; + } + if (iDefaultUrl) + { + delete iDefaultUrl; + iDefaultUrl = NULL; + } + if (iMonitor) + { + delete iMonitor; + iMonitor = NULL; + } + iRfs.Close(); +} + +void OcspClient::startOcspCheck(const char ** aCertChain, int aCertChainLen) +{ + + // clear the response + iOcspResponse->Clear(); + // build up the chain + iCertChain = aCertChain; + iCertChainLen = aCertChainLen; + // kick off the state machine + Start(); +} + +OcspResponse OcspClient::getOcspCheckResponse() +{ + // wait for completion + iMonitor->wait(); + // return the result + return *iOcspResponse; +} + +void OcspClient::cancelOcspCheck(bool doCleanup) +{ + // cancel the outstanding request (if any) + if (doCleanup) + { + if (IsActive()) + { + Cancel(); + } + } + iMonitor->notify(); +} + +void OcspClient::Start() +{ + // cancel the outstanding request (if any) + if (IsActive()) + { + Cancel(); + } + + iState = ESendOcspRequest; + SetActive(); + if (iInitialized) + { + // already initialized + CompleteRequest(); + return; + } + + // do the initialization + iCertStore->Initialize(iStatus); + iInitialized = true; +} + +void OcspClient::SendOcspRequestL() +{ + InitOcspClientL(); + iOcspClient->Check(iStatus); +} + +void OcspClient::ProcessOcspResponse() +{ + int summary = RESPONSE_CANNOT_OBTAIN_CERT_STATUS; + if (iStatus.Int() == KErrNone) + { + // set the summary + switch (iOcspClient->SummaryResult()) + { + case OCSP::EGood: + summary = RESPONSE_GOOD; + break; + case OCSP::EUnknown: + summary = RESPONSE_UNKNOWN; + break; + case OCSP::ERevoked: + summary = RESPONSE_REVOKED; + break; + } + // set the individual responses + for (TInt index = 0 ; index < iOcspClient->TransactionCount() ; ++index) + { + const TOCSPOutcome& outcome = iOcspClient->Outcome(index); + switch (outcome.iStatus) + { + case OCSP::ETransportError: + case OCSP::EClientInternalError: + case OCSP::EMalformedRequest: + case OCSP::EServerInternalError: + case OCSP::ETryLater: + case OCSP::ESignatureRequired: + case OCSP::EClientUnauthorised: + case OCSP::EUnknownResponseType: + iOcspResponse->iIndividualResponses.push_back(RESPONSE_CANNOT_OBTAIN_CERT_STATUS); + break; + case OCSP::ENoServerSpecified: + case OCSP::EInvalidURI: + iOcspResponse->iIndividualResponses.push_back(RESPONSE_INVALID_REVOCATION_SERVER_URI); + break; + case OCSP::EResponseSignatureValidationFailure: + iOcspResponse->iIndividualResponses.push_back(RESPONSE_SIGNATURE_VALIDATION_FAILURE); + break; + case OCSP::EThisUpdateTooLate: + case OCSP::EThisUpdateTooEarly: + case OCSP::ENextUpdateTooEarly: + case OCSP::ENonceMismatch: + case OCSP::EMalformedResponse: + case OCSP::EUnknownCriticalExtension: + case OCSP::EMissingCertificates: + iOcspResponse->iIndividualResponses.push_back(RESPONSE_INVALID_REVOCATION_SERVER_RESPONSE); + break; + case OCSP::EMissingNonce: + iOcspResponse->iIndividualResponses.push_back(RESPONSE_MISSING_NONCE); + break; + case OCSP::ECertificateNotValidAtValidationTime: + iOcspResponse->iIndividualResponses.push_back(RESPONSE_INVALID_CERT_STATUS_INFO); + break; + case OCSP::EValid: + switch (outcome.iResult) + { + case OCSP::EGood: + iOcspResponse->iIndividualResponses.push_back(RESPONSE_GOOD); + break; + case OCSP::EUnknown: + iOcspResponse->iIndividualResponses.push_back(RESPONSE_UNKNOWN); + break; + case OCSP::ERevoked: + iOcspResponse->iIndividualResponses.push_back(RESPONSE_REVOKED); + break; + default: + ASSERT(EFalse); + } + break; + default: + ASSERT(EFalse); + break; + } + } + } + iOcspResponse->iSummary = summary; +} + +void OcspClient::CompleteRequest() +{ + TRequestStatus* status = &iStatus; + User::RequestComplete(status,KErrNone); +} + +void OcspClient::InitOcspClientL() +{ + if (iOcspClient) + { + delete iOcspClient; + iOcspClient = NULL; + } + if (iCertArray) + { + iCertArray->ResetAndDestroy(); + delete iCertArray; + } + COCSPParameters* ocspParams = COCSPParameters::NewL(); + if (iDefaultUrl) + { + ocspParams->SetURIL(*iDefaultUrl, ETrue); + } + ocspParams->SetTransport(COCSPTransportDefault::NewL(iIap)); + ocspParams->AddAllAuthorisationSchemesL( + TUid::Uid(KCertStoreUIDForSWInstallOCSPSigning), *iCertStore); + // add the certs + if (iCertChainLen >= 2) + { + iCertArray = new(ELeave) CArrayPtrFlat(1); + std::string cert = JavaCommonUtils::base64decode(std::string(iCertChain[0], strlen(iCertChain[0]))); + TPtr8 ptr8((TUint8 *)(cert.c_str()), cert.size()); + ptr8.SetLength(cert.size()); + CX509Certificate* issuerCert = CX509Certificate::NewL(ptr8); + iCertArray->AppendL(issuerCert); + CX509Certificate* subjectCert = NULL; + for (int i = 1; i < iCertChainLen; i++) + { + subjectCert = issuerCert; + cert = JavaCommonUtils::base64decode(std::string(iCertChain[i], strlen(iCertChain[i]))); + TPtr8 ptr((TUint8 *)(cert.c_str()), cert.size()); + ptr.SetLength(cert.size()); + issuerCert = CX509Certificate::NewL(ptr); + iCertArray->AppendL(issuerCert); + ocspParams->AddCertificateL(*subjectCert, *issuerCert); + } + } + iOcspClient = COCSPClient::NewL(ocspParams); +} + +OcspResponse* OcspResponse::NewL() +{ + OcspResponse* self = new(ELeave) OcspResponse(); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; +} + +OcspResponse::OcspResponse() +{ + iIndividualResponses.clear(); + iSummary = RESPONSE_CANNOT_OBTAIN_CERT_STATUS; +} + +void OcspResponse::ConstructL() +{ +} + +OcspResponse::~OcspResponse() +{ +} + +void OcspResponse::Clear() +{ + iIndividualResponses.clear(); + iSummary = RESPONSE_CANNOT_OBTAIN_CERT_STATUS; +} + +OcspResponse& OcspResponse::operator=(const OcspResponse& x) +{ + iSummary = x.iSummary; + iIndividualResponses = x.iIndividualResponses; + return *this; +} + +OcspResponse::OcspResponse(const OcspResponse& x) +{ + *this = x; +} +