2
Copyright (C) 2009 Klaralvdalens Datakonsult AB, a KDAB Group company, info@kdab.net
3
Copyright (c) 2009 Leo Franchi <lfranchi@kde.org>
5
This library is free software; you can redistribute it and/or modify it
6
under the terms of the GNU Library General Public License as published by
7
the Free Software Foundation; either version 2 of the License, or (at your
8
option) any later version.
10
This library is distributed in the hope that it will be useful, but WITHOUT
11
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
13
License for more details.
15
You should have received a copy of the GNU Library General Public License
16
along with this library; see the file COPYING.LIB. If not, write to the
17
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21
#include "signencryptjob.h"
23
#include "contentjobbase_p.h"
24
#include "kleo/cryptobackendfactory.h"
25
#include "kleo/cryptobackend.h"
26
#include "kleo/enum.h"
27
#include "kleo/signencryptjob.h"
31
#include <kmime/kmime_message.h>
32
#include <kmime/kmime_content.h>
33
#include <kmime/kmime_util.h>
36
#include <gpgme++/global.h>
37
#include <gpgme++/signingresult.h>
38
#include <gpgme++/encryptionresult.h>
41
using namespace Message;
43
class Message::SignEncryptJobPrivate : public ContentJobBasePrivate
46
SignEncryptJobPrivate( SignEncryptJob *qq )
47
: ContentJobBasePrivate( qq )
52
KMime::Content* content;
53
std::vector<GpgME::Key> signers;
54
Kleo::CryptoMessageFormat format;
56
std::vector<GpgME::Key> encKeys;
57
QStringList recipients;
59
// copied from messagecomposer.cpp
60
bool binaryHint( Kleo::CryptoMessageFormat f )
63
case Kleo::SMIMEFormat:
64
case Kleo::SMIMEOpaqueFormat:
67
case Kleo::OpenPGPMIMEFormat:
68
case Kleo::InlineOpenPGPFormat:
73
Q_DECLARE_PUBLIC( SignEncryptJob )
76
SignEncryptJob::SignEncryptJob( QObject *parent )
77
: ContentJobBase( *new SignEncryptJobPrivate( this ), parent )
81
SignEncryptJob::~SignEncryptJob()
85
void SignEncryptJob::setContent( KMime::Content* content )
87
Q_D( SignEncryptJob );
94
void SignEncryptJob::setCryptoMessageFormat( Kleo::CryptoMessageFormat format)
96
Q_D( SignEncryptJob );
98
// There *must* be a concrete format set at this point.
99
Q_ASSERT( format == Kleo::OpenPGPMIMEFormat
100
|| format == Kleo::InlineOpenPGPFormat
101
|| format == Kleo::SMIMEFormat
102
|| format == Kleo::SMIMEOpaqueFormat );
106
void SignEncryptJob::setSigningKeys( std::vector<GpgME::Key>& signers )
108
Q_D( SignEncryptJob );
110
d->signers = signers;
113
KMime::Content* SignEncryptJob::origContent()
115
Q_D( SignEncryptJob );
122
void SignEncryptJob::setEncryptionKeys( std::vector<GpgME::Key> keys )
124
Q_D( SignEncryptJob );
129
void SignEncryptJob::setRecipients( QStringList recipients ) {
130
Q_D( SignEncryptJob );
132
d->recipients = recipients;
135
QStringList SignEncryptJob::recipients() {
136
Q_D( SignEncryptJob );
138
return d->recipients;
141
std::vector<GpgME::Key> SignEncryptJob::encryptionKeys() {
142
Q_D( SignEncryptJob );
148
void SignEncryptJob::process()
150
Q_D( SignEncryptJob );
151
Q_ASSERT( d->resultContent == 0 ); // Not processed before.
153
// if setContent hasn't been called, we assume that a subjob was added
154
// and we want to use that
155
if( !d->content || !d->content->hasContent() ) {
156
Q_ASSERT( d->subjobContents.size() == 1 );
157
d->content = d->subjobContents.first();
160
d->resultContent = new KMime::Content;
162
const Kleo::CryptoBackend::Protocol *proto = 0;
163
if( d->format & Kleo::AnyOpenPGP ) {
164
proto = Kleo::CryptoBackendFactory::instance()->openpgp();
165
} else if( d->format & Kleo::AnySMIME ) {
166
proto = Kleo::CryptoBackendFactory::instance()->smime();
172
kDebug() << "creating signencrypt from:" << proto->name() << proto->displayName();
173
std::auto_ptr<Kleo::SignEncryptJob> job( proto->signEncryptJob( !d->binaryHint( d->format ), d->format == Kleo::InlineOpenPGPFormat ) );
176
// replace simple LFs by CRLFs for all MIME supporting CryptPlugs
177
// according to RfC 2633, 3.1.1 Canonicalization
178
d->content->assemble();
180
if( d->format & Kleo::InlineOpenPGPFormat ) {
181
content = KMime::LFtoCRLF( d->content->body() );
183
content = KMime::LFtoCRLF( d->content->encodedContent() );
186
// FIXME: Make this async
187
const std::pair<GpgME::SigningResult,GpgME::EncryptionResult> res = job->exec( d->signers, d->encKeys,
192
if ( res.first.error() ) {
193
kDebug() << "signing failed:" << res.first.error().asString();
194
setError( res.first.error().code() );
195
setErrorText( QString::fromLocal8Bit( res.first.error().asString() ) );
197
if ( res.second.error() ) {
198
kDebug() << "encrypyting failed:" << res.second.error().asString();
199
setError( res.second.error().code() );
200
setErrorText( QString::fromLocal8Bit( res.second.error().asString() ) );
203
// exec'ed jobs don't delete themselves
205
QByteArray signatureHashAlgo = res.first.createdSignature( 0 ).hashAlgorithmAsString();
207
d->resultContent = Message::Util::composeHeadersAndBody( d->content, encBody, d->format, true, signatureHashAlgo );
208
// d->resultContent->setBody( signature );
212
#include "signencryptjob.moc"