/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
#if HAVE_FEATURE_GPGME # include <context.h> # include <data.h> # include <decryptionresult.h> #endif
using ::com::sun::star::uno::Sequence; using ::com::sun::star::uno::Exception; using ::com::sun::star::uno::Reference; using ::com::sun::star::task::PasswordRequestMode; using ::com::sun::star::task::PasswordRequestMode_PASSWORD_ENTER; using ::com::sun::star::task::PasswordRequestMode_PASSWORD_REENTER; using ::com::sun::star::task::XInteractionHandler;
for ( size_t nInd = 0; nInd < nLen; nInd++ )
{ // NO Encoding during conversion! // The specification says that the low byte should be used in case it is not NULL char nHighChar = static_cast<char>( aUString[nInd] >> 8 ); char nLowChar = static_cast<char>( aUString[nInd] & 0xFF ); char nChar = nLowChar ? nLowChar : nHighChar;
// tdf#93389: if the document is being restored from autorecovery, we need to add encryption // data also for real document type. // TODO: get real filter name here (from CheckPasswd_Impl), to only add necessary data bool bForSalvage = false; if (nMediaEncDataCount)
{ for (auto& val : rMediaEncData)
{ if (val.Name == "ForSalvage")
{
--nMediaEncDataCount; // don't consider this element below
val.Value >>= bForSalvage; break;
}
}
}
// try media encryption data (skip, if result is OK or ABORT) if( eResult == DocPasswordVerifierResult::WrongPassword )
{ if (nMediaEncDataCount)
{
eResult = rVerifier.verifyEncryptionData( rMediaEncData ); if( eResult == DocPasswordVerifierResult::OK )
aEncData = rMediaEncData;
}
}
// try media password (skip, if result is OK or ABORT) if( eResult == DocPasswordVerifierResult::WrongPassword )
{ if( !rMediaPassword.isEmpty() )
{
eResult = rVerifier.verifyPassword( rMediaPassword, aEncData ); if (eResult == DocPasswordVerifierResult::OK)
aPassword = rMediaPassword;
}
}
// request a password (skip, if result is OK or ABORT) if( (eResult == DocPasswordVerifierResult::WrongPassword) && rxInteractHandler.is() ) try
{
PasswordRequestMode eRequestMode = PasswordRequestMode_PASSWORD_ENTER; while( eResult == DocPasswordVerifierResult::WrongPassword )
{
rtl::Reference<DocPasswordRequest> pRequest = new DocPasswordRequest( eRequestType, eRequestMode, rDocumentUrl );
rxInteractHandler->handle( pRequest ); if( pRequest->isPassword() )
{ if( !pRequest->getPassword().isEmpty() )
eResult = rVerifier.verifyPassword( pRequest->getPassword(), aEncData ); if (eResult == DocPasswordVerifierResult::OK)
aPassword = pRequest->getPassword();
} else
{
eResult = DocPasswordVerifierResult::Abort;
}
eRequestMode = PasswordRequestMode_PASSWORD_REENTER;
}
} catch( Exception& )
{
}
if (eResult == DocPasswordVerifierResult::OK && !aPassword.isEmpty())
{ if (std::none_of(std::cbegin(aEncData), std::cend(aEncData),
[](const css::beans::NamedValue& val) { return val.Name == PACKAGE_ENCRYPTIONDATA_SHA256UTF8;
}))
{ // tdf#118639: We need ODF encryption data for autorecovery, where password // will already be unavailable, so generate and append it here
aEncData = comphelper::concatSequences(
aEncData, OStorageHelper::CreatePackageEncryptionData(aPassword));
}
if (bForSalvage)
{ // TODO: add individual methods for different target filter, and only call what's needed
// 1. Prepare binary MS formats encryption data auto aUniqueID = GenerateRandomByteSequence(16); auto aEnc97Key = GenerateStd97Key(aPassword, aUniqueID); // 2. Add MS binary and OOXML encryption data to result
aEncData = comphelper::concatSequences(
aEncData, std::initializer_list<beans::NamedValue>{
{ u"STD97EncryptionKey"_ustr, css::uno::Any(aEnc97Key) },
{ u"STD97UniqueID"_ustr, css::uno::Any(aUniqueID) },
{ u"OOXPassword"_ustr, css::uno::Any(aPassword) },
});
}
}
uno::Sequence< beans::NamedValue > aEncryptionData;
std::unique_ptr<GpgME::Context> ctx;
GpgME::initializeLibrary();
GpgME::Error err = GpgME::checkEngine(GpgME::OpenPGP); if (err) throw uno::RuntimeException(u"The GpgME library failed to initialize for the OpenPGP protocol."_ustr);
ctx.reset( GpgME::Context::createForProtocol(GpgME::OpenPGP) ); if (ctx == nullptr) throw uno::RuntimeException(u"The GpgME library failed to initialize for the OpenPGP protocol."_ustr);
ctx->setArmor(false);
for (auto& rSequence : rGpgProperties)
{ if (rSequence.getLength() == 3)
{ // take CipherValue and try to decrypt that - stop after // the first successful decryption
// ctx is setup now, let's decrypt the lot!
uno::Sequence < sal_Int8 > aVector;
rSequence[2].Value >>= aVector;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.