Add isDeVs to ostream operator
[gpgme.git] / lang / cpp / src / decryptionresult.cpp
1 /*
2   decryptionresult.cpp - wraps a gpgme keygen result
3   Copyright (C) 2004 Klarälvdalens Datakonsult AB
4   2016 Bundesamt für Sicherheit in der Informationstechnik
5   Software engineering by Intevation GmbH
6
7   This file is part of GPGME++.
8
9   GPGME++ is free software; you can redistribute it and/or
10   modify it under the terms of the GNU Library General Public
11   License as published by the Free Software Foundation; either
12   version 2 of the License, or (at your option) any later version.
13
14   GPGME++ is distributed in the hope that it will be useful,
15   but WITHOUT ANY WARRANTY; without even the implied warranty of
16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17   GNU Library General Public License for more details.
18
19   You should have received a copy of the GNU Library General Public License
20   along with GPGME++; see the file COPYING.LIB.  If not, write to the
21   Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22   Boston, MA 02110-1301, USA.
23 */
24
25 #ifdef HAVE_CONFIG_H
26  #include "config.h"
27 #endif
28
29 #include <decryptionresult.h>
30 #include "result_p.h"
31 #include "util.h"
32
33 #include <gpgme.h>
34
35 #include <algorithm>
36 #include <iterator>
37 #include <cstring>
38 #include <cstdlib>
39 #include <istream>
40
41 #include <string.h>
42
43 class GpgME::DecryptionResult::Private
44 {
45 public:
46     explicit Private(const _gpgme_op_decrypt_result &r) : res(r)
47     {
48         if (res.unsupported_algorithm) {
49             res.unsupported_algorithm = strdup(res.unsupported_algorithm);
50         }
51         if (res.file_name) {
52             res.file_name = strdup(res.file_name);
53         }
54         //FIXME: copying gpgme_recipient_t objects invalidates the keyid member,
55         //thus we use _keyid for now (internal API)
56         for (gpgme_recipient_t r = res.recipients ; r ; r = r->next) {
57             recipients.push_back(*r);
58         }
59         res.recipients = 0;
60     }
61     ~Private()
62     {
63         if (res.unsupported_algorithm) {
64             std::free(res.unsupported_algorithm);
65         }
66         res.unsupported_algorithm = 0;
67         if (res.file_name) {
68             std::free(res.file_name);
69         }
70         res.file_name = 0;
71     }
72
73     _gpgme_op_decrypt_result res;
74     std::vector<_gpgme_recipient> recipients;
75 };
76
77 GpgME::DecryptionResult::DecryptionResult(gpgme_ctx_t ctx, int error)
78     : GpgME::Result(error), d()
79 {
80     init(ctx);
81 }
82
83 GpgME::DecryptionResult::DecryptionResult(gpgme_ctx_t ctx, const Error &error)
84     : GpgME::Result(error), d()
85 {
86     init(ctx);
87 }
88
89 void GpgME::DecryptionResult::init(gpgme_ctx_t ctx)
90 {
91     if (!ctx) {
92         return;
93     }
94     gpgme_decrypt_result_t res = gpgme_op_decrypt_result(ctx);
95     if (!res) {
96         return;
97     }
98     d.reset(new Private(*res));
99 }
100
101 make_standard_stuff(DecryptionResult)
102
103 const char *GpgME::DecryptionResult::unsupportedAlgorithm() const
104 {
105     return d ? d->res.unsupported_algorithm : 0 ;
106 }
107
108 bool GpgME::DecryptionResult::isWrongKeyUsage() const
109 {
110     return d && d->res.wrong_key_usage;
111 }
112
113 bool GpgME::DecryptionResult::isDeVs() const
114 {
115     return d && d->res.is_de_vs;
116 }
117
118 const char *GpgME::DecryptionResult::fileName() const
119 {
120     return d ? d->res.file_name : 0 ;
121 }
122
123 unsigned int GpgME::DecryptionResult::numRecipients() const
124 {
125     return d ? d->recipients.size() : 0 ;
126 }
127
128 GpgME::DecryptionResult::Recipient GpgME::DecryptionResult::recipient(unsigned int idx) const
129 {
130     if (d && idx < d->recipients.size()) {
131         return Recipient(&d->recipients[idx]);
132     }
133     return Recipient();
134 }
135
136 namespace
137 {
138 struct make_recipient {
139     GpgME::DecryptionResult::Recipient operator()(_gpgme_recipient &t)
140     {
141         return GpgME::DecryptionResult::Recipient(&t);
142     }
143 };
144 }
145
146 std::vector<GpgME::DecryptionResult::Recipient> GpgME::DecryptionResult::recipients() const
147 {
148     std::vector<Recipient> result;
149     if (d) {
150         result.reserve(d->recipients.size());
151         std::transform(d->recipients.begin(), d->recipients.end(),
152                        std::back_inserter(result),
153                        make_recipient());
154     }
155     return result;
156 }
157
158 class GpgME::DecryptionResult::Recipient::Private : public _gpgme_recipient
159 {
160 public:
161     Private(gpgme_recipient_t reci) : _gpgme_recipient(*reci) {}
162 };
163
164 GpgME::DecryptionResult::Recipient::Recipient()
165     : d()
166 {
167
168 }
169
170 GpgME::DecryptionResult::Recipient::Recipient(gpgme_recipient_t r)
171     : d()
172 {
173     if (r) {
174         d.reset(new Private(r));
175     }
176 }
177
178 bool GpgME::DecryptionResult::Recipient::isNull() const
179 {
180     return !d;
181 }
182
183 const char *GpgME::DecryptionResult::Recipient::keyID() const
184 {
185     //_keyid is internal API, but the public keyid is invalid after copying (see above)
186     if (d) {
187         return d->_keyid;
188     }
189     return 0;
190 }
191
192 const char *GpgME::DecryptionResult::Recipient::shortKeyID() const
193 {
194     //_keyid is internal API, but the public keyid is invalid after copying (see above)
195     if (d) {
196         return d->_keyid + 8;
197     }
198     return 0;
199 }
200
201 unsigned int GpgME::DecryptionResult::Recipient::publicKeyAlgorithm() const
202 {
203     if (d) {
204         return d->pubkey_algo;
205     }
206     return 0;
207 }
208
209 const char *GpgME::DecryptionResult::Recipient::publicKeyAlgorithmAsString() const
210 {
211     if (d) {
212         return gpgme_pubkey_algo_name(d->pubkey_algo);
213     }
214     return 0;
215 }
216
217 GpgME::Error GpgME::DecryptionResult::Recipient::status() const
218 {
219     if (d) {
220         return Error(d->status);
221     }
222     return Error();
223 }
224
225 std::ostream &GpgME::operator<<(std::ostream &os, const DecryptionResult &result)
226 {
227     os << "GpgME::DecryptionResult(";
228     if (!result.isNull()) {
229         os << "\n error:                " << result.error()
230            << "\n fileName:             " << protect(result.fileName())
231            << "\n unsupportedAlgorithm: " << protect(result.unsupportedAlgorithm())
232            << "\n isWrongKeyUsage:      " << result.isWrongKeyUsage()
233            << "\n isDeVs                " << result.isDeVs()
234            << "\n recipients:\n";
235         const std::vector<DecryptionResult::Recipient> recipients = result.recipients();
236         std::copy(recipients.begin(), recipients.end(),
237                   std::ostream_iterator<DecryptionResult::Recipient>(os, "\n"));
238     }
239     return os << ')';
240 }
241
242 std::ostream &GpgME::operator<<(std::ostream &os, const DecryptionResult::Recipient &reci)
243 {
244     os << "GpgME::DecryptionResult::Recipient(";
245     if (!reci.isNull()) {
246         os << "\n keyID:              " << protect(reci.keyID())
247            << "\n shortKeyID:         " << protect(reci.shortKeyID())
248            << "\n publicKeyAlgorithm: " << protect(reci.publicKeyAlgorithmAsString())
249            << "\n status:             " << reci.status();
250     }
251     return os << ')';
252 }