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
39class GpgME::SigningResult::Private {
40public:
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
77GpgME::SigningResult::SigningResult( gpgme_ctx_t ctx, int error )
78 : GpgME::Result( error ), d()
79{
80 init( ctx );
81}
82
83GpgME::SigningResult::SigningResult( gpgme_ctx_t ctx, const Error & error )
84 : GpgME::Result( error ), d()
85{
86 init( ctx );
87}
88
89void 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
100make_standard_stuff(SigningResult)
101
102GpgME::CreatedSignature GpgME::SigningResult::createdSignature( unsigned int idx ) const {
103 return CreatedSignature( d, idx );
104}
105
106std::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
119GpgME::InvalidSigningKey GpgME::SigningResult::invalidSigningKey( unsigned int idx ) const {
120 return InvalidSigningKey( d, idx );
121}
122
123std::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
138GpgME::InvalidSigningKey::InvalidSigningKey( const boost::shared_ptr<SigningResult::Private> & parent, unsigned int i )
139 : d( parent ), idx( i )
140{
141
142}
143
144GpgME::InvalidSigningKey::InvalidSigningKey() : d(), idx( 0 ) {}
145
146bool GpgME::InvalidSigningKey::isNull() const {
147 return !d || idx >= d->invalid.size() ;
148}
149
150const char * GpgME::InvalidSigningKey::fingerprint() const {
151 return isNull() ? 0 : d->invalid[idx]->fpr ;
152}
153
154GpgME::Error GpgME::InvalidSigningKey::reason() const {
155 return Error( isNull() ? 0 : d->invalid[idx]->reason );
156}
157
158
159
160GpgME::CreatedSignature::CreatedSignature( const boost::shared_ptr<SigningResult::Private> & parent, unsigned int i )
161 : d( parent ), idx( i )
162{
163
164}
165
166GpgME::CreatedSignature::CreatedSignature() : d(), idx( 0 ) {}
167
168bool GpgME::CreatedSignature::isNull() const {
169 return !d || idx >= d->created.size() ;
170}
171
172const char * GpgME::CreatedSignature::fingerprint() const {
173 return isNull() ? 0 : d->created[idx]->fpr ;
174}
175
176time_t GpgME::CreatedSignature::creationTime() const {
177 return static_cast<time_t>( isNull() ? 0 : d->created[idx]->timestamp );
178}
179
180GpgME::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
192unsigned int GpgME::CreatedSignature::publicKeyAlgorithm() const {
193 return isNull() ? 0 : d->created[idx]->pubkey_algo ;
194}
195
196const char * GpgME::CreatedSignature::publicKeyAlgorithmAsString() const {
197 return gpgme_pubkey_algo_name( isNull() ? (gpgme_pubkey_algo_t)0 : d->created[idx]->pubkey_algo );
198}
199
200unsigned int GpgME::CreatedSignature::hashAlgorithm() const {
201 return isNull() ? 0 : d->created[idx]->hash_algo ;
202}
203
204const char * GpgME::CreatedSignature::hashAlgorithmAsString() const {
205 return gpgme_hash_algo_name( isNull() ? (gpgme_hash_algo_t)0 : d->created[idx]->hash_algo );
206}
207
208unsigned int GpgME::CreatedSignature::signatureClass() const {
209 return isNull() ? 0 : d->created[idx]->sig_class ;
210}
211
212
213std::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
229std::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
243std::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