1 | /* |
2 | signingresult.cpp - wraps a gpgme verify result |
3 | Copyright (C) 2004 Klarälvdalens Datakonsult AB |
4 | |
5 | This file is part of GPGME++. |
6 | |
7 | GPGME++ is free software; you can redistribute it and/or |
8 | modify it under the terms of the GNU Library General Public |
9 | License as published by the Free Software Foundation; either |
10 | version 2 of the License, or (at your option) any later version. |
11 | |
12 | GPGME++ is distributed in the hope that it will be useful, |
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
15 | GNU Library General Public License for more details. |
16 | |
17 | You should have received a copy of the GNU Library General Public License |
18 | along with GPGME++; see the file COPYING.LIB. If not, write to the |
19 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
20 | Boston, MA 02110-1301, USA. |
21 | */ |
22 | |
23 | #include <gpgme++/config-gpgme++.h> |
24 | |
25 | #include <gpgme++/signingresult.h> |
26 | #include "result_p.h" |
27 | #include "util.h" |
28 | |
29 | #include <gpgme.h> |
30 | |
31 | #include <cstring> |
32 | #include <cstdlib> |
33 | #include <algorithm> |
34 | #include <istream> |
35 | #include <iterator> |
36 | |
37 | #include <string.h> |
38 | |
39 | class GpgME::SigningResult::Private { |
40 | public: |
41 | Private( const gpgme_sign_result_t r ) { |
42 | if ( !r ) { |
43 | return; |
44 | } |
45 | for ( gpgme_new_signature_t is = r->signatures ; is ; is = is->next ) { |
46 | gpgme_new_signature_t copy = new _gpgme_new_signature( *is ); |
47 | if ( is->fpr ) { |
48 | copy->fpr = strdup( is->fpr ); |
49 | } |
50 | copy->next = 0; |
51 | created.push_back( copy ); |
52 | } |
53 | for ( gpgme_invalid_key_t ik = r->invalid_signers ; ik ; ik = ik->next ) { |
54 | gpgme_invalid_key_t copy = new _gpgme_invalid_key( *ik ); |
55 | if ( ik->fpr ) { |
56 | copy->fpr = strdup( ik->fpr ); |
57 | } |
58 | copy->next = 0; |
59 | invalid.push_back( copy ); |
60 | } |
61 | } |
62 | ~Private() { |
63 | for ( std::vector<gpgme_new_signature_t>::iterator it = created.begin() ; it != created.end() ; ++it ) { |
64 | std::free( ( *it )->fpr ); |
65 | delete *it; *it = 0; |
66 | } |
67 | for ( std::vector<gpgme_invalid_key_t>::iterator it = invalid.begin() ; it != invalid.end() ; ++it ) { |
68 | std::free( ( *it )->fpr ); |
69 | delete *it; *it = 0; |
70 | } |
71 | } |
72 | |
73 | std::vector<gpgme_new_signature_t> created; |
74 | std::vector<gpgme_invalid_key_t> invalid; |
75 | }; |
76 | |
77 | GpgME::SigningResult::SigningResult( gpgme_ctx_t ctx, int error ) |
78 | : GpgME::Result( error ), d() |
79 | { |
80 | init( ctx ); |
81 | } |
82 | |
83 | GpgME::SigningResult::SigningResult( gpgme_ctx_t ctx, const Error & error ) |
84 | : GpgME::Result( error ), d() |
85 | { |
86 | init( ctx ); |
87 | } |
88 | |
89 | void GpgME::SigningResult::init( gpgme_ctx_t ctx ) { |
90 | if ( !ctx ) { |
91 | return; |
92 | } |
93 | gpgme_sign_result_t res = gpgme_op_sign_result( ctx ); |
94 | if ( !res ) { |
95 | return; |
96 | } |
97 | d.reset( new Private( res ) ); |
98 | } |
99 | |
100 | make_standard_stuff(SigningResult) |
101 | |
102 | GpgME::CreatedSignature GpgME::SigningResult::createdSignature( unsigned int idx ) const { |
103 | return CreatedSignature( d, idx ); |
104 | } |
105 | |
106 | std::vector<GpgME::CreatedSignature> GpgME::SigningResult::createdSignatures() const { |
107 | if ( !d ) { |
108 | return std::vector<CreatedSignature>(); |
109 | } |
110 | std::vector<CreatedSignature> result; |
111 | result.reserve( d->created.size() ); |
112 | for ( unsigned int i = 0 ; i < d->created.size() ; ++i ) { |
113 | result.push_back( CreatedSignature( d, i ) ); |
114 | } |
115 | return result; |
116 | } |
117 | |
118 | |
119 | GpgME::InvalidSigningKey GpgME::SigningResult::invalidSigningKey( unsigned int idx ) const { |
120 | return InvalidSigningKey( d, idx ); |
121 | } |
122 | |
123 | std::vector<GpgME::InvalidSigningKey> GpgME::SigningResult::invalidSigningKeys() const { |
124 | if ( !d ) { |
125 | return std::vector<GpgME::InvalidSigningKey>(); |
126 | } |
127 | std::vector<GpgME::InvalidSigningKey> result; |
128 | result.reserve( d->invalid.size() ); |
129 | for ( unsigned int i = 0 ; i < d->invalid.size() ; ++i ) { |
130 | result.push_back( InvalidSigningKey( d, i ) ); |
131 | } |
132 | return result; |
133 | } |
134 | |
135 | |
136 | |
137 | |
138 | GpgME::InvalidSigningKey::InvalidSigningKey( const boost::shared_ptr<SigningResult::Private> & parent, unsigned int i ) |
139 | : d( parent ), idx( i ) |
140 | { |
141 | |
142 | } |
143 | |
144 | GpgME::InvalidSigningKey::InvalidSigningKey() : d(), idx( 0 ) {} |
145 | |
146 | bool GpgME::InvalidSigningKey::isNull() const { |
147 | return !d || idx >= d->invalid.size() ; |
148 | } |
149 | |
150 | const char * GpgME::InvalidSigningKey::fingerprint() const { |
151 | return isNull() ? 0 : d->invalid[idx]->fpr ; |
152 | } |
153 | |
154 | GpgME::Error GpgME::InvalidSigningKey::reason() const { |
155 | return Error( isNull() ? 0 : d->invalid[idx]->reason ); |
156 | } |
157 | |
158 | |
159 | |
160 | GpgME::CreatedSignature::CreatedSignature( const boost::shared_ptr<SigningResult::Private> & parent, unsigned int i ) |
161 | : d( parent ), idx( i ) |
162 | { |
163 | |
164 | } |
165 | |
166 | GpgME::CreatedSignature::CreatedSignature() : d(), idx( 0 ) {} |
167 | |
168 | bool GpgME::CreatedSignature::isNull() const { |
169 | return !d || idx >= d->created.size() ; |
170 | } |
171 | |
172 | const char * GpgME::CreatedSignature::fingerprint() const { |
173 | return isNull() ? 0 : d->created[idx]->fpr ; |
174 | } |
175 | |
176 | time_t GpgME::CreatedSignature::creationTime() const { |
177 | return static_cast<time_t>( isNull() ? 0 : d->created[idx]->timestamp ); |
178 | } |
179 | |
180 | GpgME::SignatureMode GpgME::CreatedSignature::mode() const { |
181 | if ( isNull() ) { |
182 | return NormalSignatureMode; |
183 | } |
184 | switch ( d->created[idx]->type ) { |
185 | default: |
186 | case GPGME_SIG_MODE_NORMAL: return NormalSignatureMode; |
187 | case GPGME_SIG_MODE_DETACH: return Detached; |
188 | case GPGME_SIG_MODE_CLEAR: return Clearsigned; |
189 | } |
190 | } |
191 | |
192 | unsigned int GpgME::CreatedSignature::publicKeyAlgorithm() const { |
193 | return isNull() ? 0 : d->created[idx]->pubkey_algo ; |
194 | } |
195 | |
196 | const char * GpgME::CreatedSignature::publicKeyAlgorithmAsString() const { |
197 | return gpgme_pubkey_algo_name( isNull() ? (gpgme_pubkey_algo_t)0 : d->created[idx]->pubkey_algo ); |
198 | } |
199 | |
200 | unsigned int GpgME::CreatedSignature::hashAlgorithm() const { |
201 | return isNull() ? 0 : d->created[idx]->hash_algo ; |
202 | } |
203 | |
204 | const char * GpgME::CreatedSignature::hashAlgorithmAsString() const { |
205 | return gpgme_hash_algo_name( isNull() ? (gpgme_hash_algo_t)0 : d->created[idx]->hash_algo ); |
206 | } |
207 | |
208 | unsigned int GpgME::CreatedSignature::signatureClass() const { |
209 | return isNull() ? 0 : d->created[idx]->sig_class ; |
210 | } |
211 | |
212 | |
213 | std::ostream & GpgME::operator<<( std::ostream & os, const SigningResult & result ) { |
214 | os << "GpgME::SigningResult(" ; |
215 | if ( !result.isNull() ) { |
216 | os << "\n error: " << result.error() |
217 | << "\n createdSignatures:\n" ; |
218 | const std::vector<CreatedSignature> cs = result.createdSignatures(); |
219 | std::copy( cs.begin(), cs.end(), |
220 | std::ostream_iterator<CreatedSignature>( os, "\n" ) ); |
221 | os << " invalidSigningKeys:\n" ; |
222 | const std::vector<InvalidSigningKey> isk = result.invalidSigningKeys(); |
223 | std::copy( isk.begin(), isk.end(), |
224 | std::ostream_iterator<InvalidSigningKey>( os, "\n" ) ); |
225 | } |
226 | return os << ')'; |
227 | } |
228 | |
229 | std::ostream & GpgME::operator<<( std::ostream & os, const CreatedSignature & sig ) { |
230 | os << "GpgME::CreatedSignature(" ; |
231 | if ( !sig.isNull() ) { |
232 | os << "\n fingerprint: " << protect( sig.fingerprint() ) |
233 | << "\n creationTime: " << sig.creationTime() |
234 | << "\n mode: " << sig.mode() |
235 | << "\n publicKeyAlgorithm: " << protect( sig.publicKeyAlgorithmAsString() ) |
236 | << "\n hashAlgorithm: " << protect( sig.hashAlgorithmAsString() ) |
237 | << "\n signatureClass: " << sig.signatureClass() |
238 | << '\n'; |
239 | } |
240 | return os << ')'; |
241 | } |
242 | |
243 | std::ostream & GpgME::operator<<( std::ostream & os, const InvalidSigningKey & key ) { |
244 | os << "GpgME::InvalidSigningKey(" ; |
245 | if ( !key.isNull() ) { |
246 | os << "\n fingerprint: " << protect( key.fingerprint() ) |
247 | << "\n reason: " << key.reason() |
248 | << '\n'; |
249 | } |
250 | return os << ')'; |
251 | } |
252 | |