Blame lang/cpp/src/decryptionresult.cpp

Packit d7e8d0
/*
Packit d7e8d0
  decryptionresult.cpp - wraps a gpgme keygen result
Packit d7e8d0
  Copyright (C) 2004 Klarälvdalens Datakonsult AB
Packit d7e8d0
  2016 Bundesamt für Sicherheit in der Informationstechnik
Packit d7e8d0
  Software engineering by Intevation GmbH
Packit d7e8d0
Packit d7e8d0
  This file is part of GPGME++.
Packit d7e8d0
Packit d7e8d0
  GPGME++ is free software; you can redistribute it and/or
Packit d7e8d0
  modify it under the terms of the GNU Library General Public
Packit d7e8d0
  License as published by the Free Software Foundation; either
Packit d7e8d0
  version 2 of the License, or (at your option) any later version.
Packit d7e8d0
Packit d7e8d0
  GPGME++ is distributed in the hope that it will be useful,
Packit d7e8d0
  but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit d7e8d0
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit d7e8d0
  GNU Library General Public License for more details.
Packit d7e8d0
Packit d7e8d0
  You should have received a copy of the GNU Library General Public License
Packit d7e8d0
  along with GPGME++; see the file COPYING.LIB.  If not, write to the
Packit d7e8d0
  Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Packit d7e8d0
  Boston, MA 02110-1301, USA.
Packit d7e8d0
*/
Packit d7e8d0
Packit d7e8d0
#ifdef HAVE_CONFIG_H
Packit d7e8d0
 #include "config.h"
Packit d7e8d0
#endif
Packit d7e8d0
Packit d7e8d0
#include <decryptionresult.h>
Packit d7e8d0
#include "result_p.h"
Packit d7e8d0
#include "util.h"
Packit d7e8d0
Packit d7e8d0
#include <gpgme.h>
Packit d7e8d0
Packit d7e8d0
#include <algorithm>
Packit d7e8d0
#include <iterator>
Packit d7e8d0
#include <cstring>
Packit d7e8d0
#include <cstdlib>
Packit d7e8d0
#include <istream>
Packit d7e8d0
Packit d7e8d0
#include <string.h>
Packit d7e8d0
Packit d7e8d0
class GpgME::DecryptionResult::Private
Packit d7e8d0
{
Packit d7e8d0
public:
Packit d7e8d0
    explicit Private(const _gpgme_op_decrypt_result &r) : res(r)
Packit d7e8d0
    {
Packit d7e8d0
        if (res.unsupported_algorithm) {
Packit d7e8d0
            res.unsupported_algorithm = strdup(res.unsupported_algorithm);
Packit d7e8d0
        }
Packit d7e8d0
        if (res.file_name) {
Packit d7e8d0
            res.file_name = strdup(res.file_name);
Packit d7e8d0
        }
Packit Service 30b792
        if (res.symkey_algo) {
Packit Service 30b792
            res.symkey_algo = strdup(res.symkey_algo);
Packit Service 30b792
        }
Packit d7e8d0
        //FIXME: copying gpgme_recipient_t objects invalidates the keyid member,
Packit d7e8d0
        //thus we use _keyid for now (internal API)
Packit d7e8d0
        for (gpgme_recipient_t r = res.recipients ; r ; r = r->next) {
Packit d7e8d0
            recipients.push_back(*r);
Packit d7e8d0
        }
Packit Service 30b792
        res.recipients = nullptr;
Packit d7e8d0
    }
Packit d7e8d0
    ~Private()
Packit d7e8d0
    {
Packit d7e8d0
        if (res.unsupported_algorithm) {
Packit d7e8d0
            std::free(res.unsupported_algorithm);
Packit d7e8d0
        }
Packit Service 30b792
        res.unsupported_algorithm = nullptr;
Packit d7e8d0
        if (res.file_name) {
Packit d7e8d0
            std::free(res.file_name);
Packit d7e8d0
        }
Packit Service 30b792
        res.file_name = nullptr;
Packit Service 30b792
        if (res.symkey_algo) {
Packit Service 30b792
            std::free(res.symkey_algo);
Packit Service 30b792
        }
Packit Service 30b792
        res.symkey_algo = nullptr;
Packit d7e8d0
    }
Packit d7e8d0
Packit d7e8d0
    _gpgme_op_decrypt_result res;
Packit d7e8d0
    std::vector<_gpgme_recipient> recipients;
Packit d7e8d0
};
Packit d7e8d0
Packit d7e8d0
GpgME::DecryptionResult::DecryptionResult(gpgme_ctx_t ctx, int error)
Packit d7e8d0
    : GpgME::Result(error), d()
Packit d7e8d0
{
Packit d7e8d0
    init(ctx);
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
GpgME::DecryptionResult::DecryptionResult(gpgme_ctx_t ctx, const Error &error)
Packit d7e8d0
    : GpgME::Result(error), d()
Packit d7e8d0
{
Packit d7e8d0
    init(ctx);
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
void GpgME::DecryptionResult::init(gpgme_ctx_t ctx)
Packit d7e8d0
{
Packit d7e8d0
    if (!ctx) {
Packit d7e8d0
        return;
Packit d7e8d0
    }
Packit d7e8d0
    gpgme_decrypt_result_t res = gpgme_op_decrypt_result(ctx);
Packit d7e8d0
    if (!res) {
Packit d7e8d0
        return;
Packit d7e8d0
    }
Packit d7e8d0
    d.reset(new Private(*res));
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
make_standard_stuff(DecryptionResult)
Packit d7e8d0
Packit d7e8d0
const char *GpgME::DecryptionResult::unsupportedAlgorithm() const
Packit d7e8d0
{
Packit Service 30b792
    return d ? d->res.unsupported_algorithm : nullptr ;
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
bool GpgME::DecryptionResult::isWrongKeyUsage() const
Packit d7e8d0
{
Packit d7e8d0
    return d && d->res.wrong_key_usage;
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
bool GpgME::DecryptionResult::isDeVs() const
Packit d7e8d0
{
Packit d7e8d0
    return d && d->res.is_de_vs;
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
const char *GpgME::DecryptionResult::fileName() const
Packit d7e8d0
{
Packit Service 30b792
    return d ? d->res.file_name : nullptr ;
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
unsigned int GpgME::DecryptionResult::numRecipients() const
Packit d7e8d0
{
Packit d7e8d0
    return d ? d->recipients.size() : 0 ;
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
GpgME::DecryptionResult::Recipient GpgME::DecryptionResult::recipient(unsigned int idx) const
Packit d7e8d0
{
Packit d7e8d0
    if (d && idx < d->recipients.size()) {
Packit d7e8d0
        return Recipient(&d->recipients[idx]);
Packit d7e8d0
    }
Packit d7e8d0
    return Recipient();
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
namespace
Packit d7e8d0
{
Packit d7e8d0
struct make_recipient {
Packit d7e8d0
    GpgME::DecryptionResult::Recipient operator()(_gpgme_recipient &t)
Packit d7e8d0
    {
Packit d7e8d0
        return GpgME::DecryptionResult::Recipient(&t);
Packit d7e8d0
    }
Packit d7e8d0
};
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
std::vector<GpgME::DecryptionResult::Recipient> GpgME::DecryptionResult::recipients() const
Packit d7e8d0
{
Packit d7e8d0
    std::vector<Recipient> result;
Packit d7e8d0
    if (d) {
Packit d7e8d0
        result.reserve(d->recipients.size());
Packit d7e8d0
        std::transform(d->recipients.begin(), d->recipients.end(),
Packit d7e8d0
                       std::back_inserter(result),
Packit d7e8d0
                       make_recipient());
Packit d7e8d0
    }
Packit d7e8d0
    return result;
Packit d7e8d0
}
Packit d7e8d0
Packit Service 30b792
const char *GpgME::DecryptionResult::sessionKey() const
Packit Service 30b792
{
Packit Service 30b792
  return d ? d->res.session_key : nullptr;
Packit Service 30b792
}
Packit Service 30b792
Packit Service 30b792
const char *GpgME::DecryptionResult::symkeyAlgo() const
Packit Service 30b792
{
Packit Service 30b792
  return d ? d->res.symkey_algo : nullptr;
Packit Service 30b792
}
Packit Service 30b792
Packit Service 30b792
bool GpgME::DecryptionResult::isLegacyCipherNoMDC() const
Packit Service 30b792
{
Packit Service 30b792
  return d && d->res.legacy_cipher_nomdc;
Packit Service 30b792
}
Packit Service 30b792
Packit d7e8d0
class GpgME::DecryptionResult::Recipient::Private : public _gpgme_recipient
Packit d7e8d0
{
Packit d7e8d0
public:
Packit d7e8d0
    Private(gpgme_recipient_t reci) : _gpgme_recipient(*reci) {}
Packit d7e8d0
};
Packit d7e8d0
Packit d7e8d0
GpgME::DecryptionResult::Recipient::Recipient()
Packit d7e8d0
    : d()
Packit d7e8d0
{
Packit d7e8d0
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
GpgME::DecryptionResult::Recipient::Recipient(gpgme_recipient_t r)
Packit d7e8d0
    : d()
Packit d7e8d0
{
Packit d7e8d0
    if (r) {
Packit d7e8d0
        d.reset(new Private(r));
Packit d7e8d0
    }
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
bool GpgME::DecryptionResult::Recipient::isNull() const
Packit d7e8d0
{
Packit d7e8d0
    return !d;
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
const char *GpgME::DecryptionResult::Recipient::keyID() const
Packit d7e8d0
{
Packit d7e8d0
    //_keyid is internal API, but the public keyid is invalid after copying (see above)
Packit d7e8d0
    if (d) {
Packit d7e8d0
        return d->_keyid;
Packit d7e8d0
    }
Packit Service 30b792
    return nullptr;
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
const char *GpgME::DecryptionResult::Recipient::shortKeyID() const
Packit d7e8d0
{
Packit d7e8d0
    //_keyid is internal API, but the public keyid is invalid after copying (see above)
Packit d7e8d0
    if (d) {
Packit d7e8d0
        return d->_keyid + 8;
Packit d7e8d0
    }
Packit Service 30b792
    return nullptr;
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
unsigned int GpgME::DecryptionResult::Recipient::publicKeyAlgorithm() const
Packit d7e8d0
{
Packit d7e8d0
    if (d) {
Packit d7e8d0
        return d->pubkey_algo;
Packit d7e8d0
    }
Packit d7e8d0
    return 0;
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
const char *GpgME::DecryptionResult::Recipient::publicKeyAlgorithmAsString() const
Packit d7e8d0
{
Packit d7e8d0
    if (d) {
Packit d7e8d0
        return gpgme_pubkey_algo_name(d->pubkey_algo);
Packit d7e8d0
    }
Packit Service 30b792
    return nullptr;
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
GpgME::Error GpgME::DecryptionResult::Recipient::status() const
Packit d7e8d0
{
Packit d7e8d0
    if (d) {
Packit d7e8d0
        return Error(d->status);
Packit d7e8d0
    }
Packit d7e8d0
    return Error();
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
std::ostream &GpgME::operator<<(std::ostream &os, const DecryptionResult &result)
Packit d7e8d0
{
Packit d7e8d0
    os << "GpgME::DecryptionResult(";
Packit d7e8d0
    if (!result.isNull()) {
Packit d7e8d0
        os << "\n error:                " << result.error()
Packit d7e8d0
           << "\n fileName:             " << protect(result.fileName())
Packit d7e8d0
           << "\n unsupportedAlgorithm: " << protect(result.unsupportedAlgorithm())
Packit d7e8d0
           << "\n isWrongKeyUsage:      " << result.isWrongKeyUsage()
Packit d7e8d0
           << "\n isDeVs                " << result.isDeVs()
Packit Service 30b792
           << "\n legacyCipherNoMDC     " << result.isLegacyCipherNoMDC()
Packit Service 30b792
           << "\n symkeyAlgo:           " << protect(result.symkeyAlgo())
Packit d7e8d0
           << "\n recipients:\n";
Packit d7e8d0
        const std::vector<DecryptionResult::Recipient> recipients = result.recipients();
Packit d7e8d0
        std::copy(recipients.begin(), recipients.end(),
Packit d7e8d0
                  std::ostream_iterator<DecryptionResult::Recipient>(os, "\n"));
Packit d7e8d0
    }
Packit d7e8d0
    return os << ')';
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
std::ostream &GpgME::operator<<(std::ostream &os, const DecryptionResult::Recipient &reci)
Packit d7e8d0
{
Packit d7e8d0
    os << "GpgME::DecryptionResult::Recipient(";
Packit d7e8d0
    if (!reci.isNull()) {
Packit d7e8d0
        os << "\n keyID:              " << protect(reci.keyID())
Packit d7e8d0
           << "\n shortKeyID:         " << protect(reci.shortKeyID())
Packit d7e8d0
           << "\n publicKeyAlgorithm: " << protect(reci.publicKeyAlgorithmAsString())
Packit d7e8d0
           << "\n status:             " << reci.status();
Packit d7e8d0
    }
Packit d7e8d0
    return os << ')';
Packit d7e8d0
}