30 #include "kleo/oidmap.h"
32 #include <gpgmepp/context.h>
33 #include <gpgmepp/data.h>
34 #include <gpgmepp/importresult.h>
70 #define __GPGMEPLUG_ERROR_CLEARTEXT_IS_ZERO "Error: Cannot run checkMessageSignature() with cleartext == 0"
77 #ifndef GPGMEPLUG_ENCSIGN_MAKE_MIME_OBJECT
78 #define GPGMEPLUG_ENCSIGN_INCLUDE_CLEARTEXT false
79 #define GPGMEPLUG_ENCSIGN_MAKE_MIME_OBJECT false
80 #define GPGMEPLUG_ENCSIGN_MAKE_MULTI_MIME false
81 #define GPGMEPLUG_ENCSIGN_CTYPE_MAIN ""
82 #define GPGMEPLUG_ENCSIGN_CDISP_MAIN ""
83 #define GPGMEPLUG_ENCSIGN_CTENC_MAIN ""
84 #define GPGMEPLUG_ENCSIGN_CTYPE_VERSION ""
85 #define GPGMEPLUG_ENCSIGN_CDISP_VERSION ""
86 #define GPGMEPLUG_ENCSIGN_CTENC_VERSION ""
87 #define GPGMEPLUG_ENCSIGN_BTEXT_VERSION ""
88 #define GPGMEPLUG_ENCSIGN_CTYPE_CODE ""
89 #define GPGMEPLUG_ENCSIGN_CDISP_CODE ""
90 #define GPGMEPLUG_ENCSIGN_CTENC_CODE ""
91 #define GPGMEPLUG_ENCSIGN_FLAT_PREFIX ""
92 #define GPGMEPLUG_ENCSIGN_FLAT_SEPARATOR ""
93 #define GPGMEPLUG_ENCSIGN_FLAT_POSTFIX ""
99 SMIMECryptPlug::SMIMECryptPlug() : CryptPlug() {
100 GPGMEPLUG_PROTOCOL = GPGME_PROTOCOL_CMS;
101 mProtocol = GpgME::Context::CMS;
105 GPGMEPLUG_OPA_SIGN_INCLUDE_CLEARTEXT =
false;
106 GPGMEPLUG_OPA_SIGN_MAKE_MIME_OBJECT =
true;
107 GPGMEPLUG_OPA_SIGN_MAKE_MULTI_MIME =
false;
108 GPGMEPLUG_OPA_SIGN_CTYPE_MAIN =
"application/pkcs7-mime; smime-type=signed-data; name=\"smime.p7m\"";
109 GPGMEPLUG_OPA_SIGN_CDISP_MAIN =
"attachment; filename=\"smime.p7m\"";
110 GPGMEPLUG_OPA_SIGN_CTENC_MAIN =
"base64";
111 GPGMEPLUG_OPA_SIGN_CTYPE_VERSION =
"";
112 GPGMEPLUG_OPA_SIGN_CDISP_VERSION =
"";
113 GPGMEPLUG_OPA_SIGN_CTENC_VERSION =
"";
114 GPGMEPLUG_OPA_SIGN_BTEXT_VERSION =
"";
115 GPGMEPLUG_OPA_SIGN_CTYPE_CODE =
"";
116 GPGMEPLUG_OPA_SIGN_CDISP_CODE =
"";
117 GPGMEPLUG_OPA_SIGN_CTENC_CODE =
"";
118 GPGMEPLUG_OPA_SIGN_FLAT_PREFIX =
"";
119 GPGMEPLUG_OPA_SIGN_FLAT_SEPARATOR =
"";
120 GPGMEPLUG_OPA_SIGN_FLAT_POSTFIX =
"";
122 GPGMEPLUG_DET_SIGN_INCLUDE_CLEARTEXT =
true;
123 GPGMEPLUG_DET_SIGN_MAKE_MIME_OBJECT =
true;
124 GPGMEPLUG_DET_SIGN_MAKE_MULTI_MIME =
true;
125 GPGMEPLUG_DET_SIGN_CTYPE_MAIN =
"multipart/signed; protocol=\"application/pkcs7-signature\"; micalg=sha1";
126 GPGMEPLUG_DET_SIGN_CDISP_MAIN =
"";
127 GPGMEPLUG_DET_SIGN_CTENC_MAIN =
"";
128 GPGMEPLUG_DET_SIGN_CTYPE_VERSION =
"";
129 GPGMEPLUG_DET_SIGN_CDISP_VERSION =
"";
130 GPGMEPLUG_DET_SIGN_CTENC_VERSION =
"";
131 GPGMEPLUG_DET_SIGN_BTEXT_VERSION =
"";
132 GPGMEPLUG_DET_SIGN_CTYPE_CODE =
"application/pkcs7-signature; name=\"smime.p7s\"";
133 GPGMEPLUG_DET_SIGN_CDISP_CODE =
"attachment; filename=\"smime.p7s\"";
134 GPGMEPLUG_DET_SIGN_CTENC_CODE =
"base64";
135 GPGMEPLUG_DET_SIGN_FLAT_PREFIX =
"";
136 GPGMEPLUG_DET_SIGN_FLAT_SEPARATOR =
"";
137 GPGMEPLUG_DET_SIGN_FLAT_POSTFIX =
"";
139 __GPGMEPLUG_SIGNATURE_CODE_IS_BINARY =
true;
142 GPGMEPLUG_ENC_INCLUDE_CLEARTEXT =
false;
143 GPGMEPLUG_ENC_MAKE_MIME_OBJECT =
true;
144 GPGMEPLUG_ENC_MAKE_MULTI_MIME =
false;
145 GPGMEPLUG_ENC_CTYPE_MAIN =
"application/pkcs7-mime; smime-type=enveloped-data; name=\"smime.p7m\"";
146 GPGMEPLUG_ENC_CDISP_MAIN =
"attachment; filename=\"smime.p7m\"";
147 GPGMEPLUG_ENC_CTENC_MAIN =
"base64";
148 GPGMEPLUG_ENC_CTYPE_VERSION =
"";
149 GPGMEPLUG_ENC_CDISP_VERSION =
"";
150 GPGMEPLUG_ENC_CTENC_VERSION =
"";
151 GPGMEPLUG_ENC_BTEXT_VERSION =
"";
152 GPGMEPLUG_ENC_CTYPE_CODE =
"";
153 GPGMEPLUG_ENC_CDISP_CODE =
"";
154 GPGMEPLUG_ENC_CTENC_CODE =
"";
155 GPGMEPLUG_ENC_FLAT_PREFIX =
"";
156 GPGMEPLUG_ENC_FLAT_SEPARATOR =
"";
157 GPGMEPLUG_ENC_FLAT_POSTFIX =
"";
158 __GPGMEPLUG_ENCRYPTED_CODE_IS_BINARY =
true;
161 OpenPGPCryptPlug::OpenPGPCryptPlug() : CryptPlug() {
162 GPGMEPLUG_PROTOCOL = GPGME_PROTOCOL_OpenPGP;
163 mProtocol = GpgME::Context::OpenPGP;
167 GPGMEPLUG_OPA_SIGN_INCLUDE_CLEARTEXT =
false;
168 GPGMEPLUG_OPA_SIGN_MAKE_MIME_OBJECT =
false;
169 GPGMEPLUG_OPA_SIGN_MAKE_MULTI_MIME =
false;
170 GPGMEPLUG_OPA_SIGN_CTYPE_MAIN =
"";
171 GPGMEPLUG_OPA_SIGN_CDISP_MAIN =
"";
172 GPGMEPLUG_OPA_SIGN_CTENC_MAIN =
"";
173 GPGMEPLUG_OPA_SIGN_CTYPE_VERSION =
"";
174 GPGMEPLUG_OPA_SIGN_CDISP_VERSION =
"";
175 GPGMEPLUG_OPA_SIGN_CTENC_VERSION =
"";
176 GPGMEPLUG_OPA_SIGN_BTEXT_VERSION =
"";
177 GPGMEPLUG_OPA_SIGN_CTYPE_CODE =
"";
178 GPGMEPLUG_OPA_SIGN_CDISP_CODE =
"";
179 GPGMEPLUG_OPA_SIGN_CTENC_CODE =
"";
180 GPGMEPLUG_OPA_SIGN_FLAT_PREFIX =
"";
181 GPGMEPLUG_OPA_SIGN_FLAT_SEPARATOR =
"";
182 GPGMEPLUG_OPA_SIGN_FLAT_POSTFIX =
"";
184 GPGMEPLUG_DET_SIGN_INCLUDE_CLEARTEXT =
true;
185 GPGMEPLUG_DET_SIGN_MAKE_MIME_OBJECT =
true;
186 GPGMEPLUG_DET_SIGN_MAKE_MULTI_MIME =
true;
187 GPGMEPLUG_DET_SIGN_CTYPE_MAIN =
"multipart/signed; protocol=\"application/pgp-signature\"; micalg=pgp-sha1";
188 GPGMEPLUG_DET_SIGN_CDISP_MAIN =
"";
189 GPGMEPLUG_DET_SIGN_CTENC_MAIN =
"";
190 GPGMEPLUG_DET_SIGN_CTYPE_VERSION =
"";
191 GPGMEPLUG_DET_SIGN_CDISP_VERSION =
"";
192 GPGMEPLUG_DET_SIGN_CTENC_VERSION =
"";
193 GPGMEPLUG_DET_SIGN_BTEXT_VERSION =
"";
194 GPGMEPLUG_DET_SIGN_CTYPE_CODE =
"application/pgp-signature";
195 GPGMEPLUG_DET_SIGN_CDISP_CODE =
"";
196 GPGMEPLUG_DET_SIGN_CTENC_CODE =
"";
197 GPGMEPLUG_DET_SIGN_FLAT_PREFIX =
"";
198 GPGMEPLUG_DET_SIGN_FLAT_SEPARATOR =
"";
199 GPGMEPLUG_DET_SIGN_FLAT_POSTFIX =
"";
201 __GPGMEPLUG_SIGNATURE_CODE_IS_BINARY =
false;
204 GPGMEPLUG_ENC_INCLUDE_CLEARTEXT =
false;
205 GPGMEPLUG_ENC_MAKE_MIME_OBJECT =
true;
206 GPGMEPLUG_ENC_MAKE_MULTI_MIME =
true;
207 GPGMEPLUG_ENC_CTYPE_MAIN =
"multipart/encrypted; protocol=\"application/pgp-encrypted\"";
208 GPGMEPLUG_ENC_CDISP_MAIN =
"";
209 GPGMEPLUG_ENC_CTENC_MAIN =
"";
210 GPGMEPLUG_ENC_CTYPE_VERSION =
"application/pgp-encrypted";
211 GPGMEPLUG_ENC_CDISP_VERSION =
"attachment";
212 GPGMEPLUG_ENC_CTENC_VERSION =
"";
213 GPGMEPLUG_ENC_BTEXT_VERSION =
"Version: 1";
214 GPGMEPLUG_ENC_CTYPE_CODE =
"application/octet-stream";
215 GPGMEPLUG_ENC_CDISP_CODE =
"inline; filename=\"msg.asc\"";
216 GPGMEPLUG_ENC_CTENC_CODE =
"";
217 GPGMEPLUG_ENC_FLAT_PREFIX =
"";
218 GPGMEPLUG_ENC_FLAT_SEPARATOR =
"";
219 GPGMEPLUG_ENC_FLAT_POSTFIX =
"";
220 __GPGMEPLUG_ENCRYPTED_CODE_IS_BINARY =
false;
223 #define days_from_seconds(x) ((x)/86400)
226 #define MAX_GPGME_IDX 20
229 #define spacep(p) (*(p) == ' ' || *(p) == '\t')
230 #define digitp(p) (*(p) >= '0' && *(p) <= '9')
231 #define hexdigitp(a) (digitp (a) \
232 || (*(a) >= 'A' && *(a) <= 'F') \
233 || (*(a) >= 'a' && *(a) <= 'f'))
235 #define atoi_1(p) (*(p) - '0' )
236 #define atoi_2(p) ((atoi_1(p) * 10) + atoi_1((p)+1))
237 #define atoi_4(p) ((atoi_2(p) * 100) + atoi_2((p)+2))
238 #define xtoi_1(p) (*(p) <= '9'? (*(p)- '0'): \
239 *(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10))
240 #define xtoi_2(p) ((xtoi_1(p) * 16) + xtoi_1((p)+1))
245 void *p = malloc (n);
248 fputs (
"\nfatal: out of core\n", stderr);
258 xstrdup (
const char *
string)
260 char *p = (
char*)xmalloc (strlen (
string)+1);
266 CryptPlug::CryptPlug() {
269 CryptPlug::~CryptPlug() {
272 bool CryptPlug::initialize() {
273 GpgME::setDefaultLocale( LC_CTYPE, setlocale( LC_CTYPE, 0 ) );
274 GpgME::setDefaultLocale( LC_MESSAGES, setlocale( LC_MESSAGES, 0 ) );
275 return (gpgme_engine_check_version (GPGMEPLUG_PROTOCOL) == GPG_ERR_NO_ERROR);
279 bool CryptPlug::hasFeature( Feature flag )
283 case Feature_SignMessages:
284 case Feature_VerifySignatures:
285 case Feature_EncryptMessages:
286 case Feature_DecryptMessages:
287 case Feature_SendCertificates:
288 case Feature_PinEntrySettings:
289 case Feature_StoreMessagesWithSigs:
290 case Feature_EncryptionCRLs:
291 case Feature_StoreMessagesEncrypted:
292 case Feature_CheckCertificatePath:
294 case Feature_WarnSignCertificateExpiry:
295 case Feature_WarnSignEmailNotInCertificate:
296 case Feature_WarnEncryptCertificateExpiry:
297 case Feature_WarnEncryptEmailNotInCertificate:
298 return GPGMEPLUG_PROTOCOL == GPGME_PROTOCOL_CMS;
300 case Feature_CRLDirectoryService:
301 case Feature_CertificateDirectoryService:
310 void storeNewCharPtr(
char** dest,
const char* src )
312 int sLen = strlen( src );
313 *dest = (
char*)xmalloc( sLen + 1 );
314 strcpy( *dest, src );
317 bool CryptPlug::decryptMessage(
const char* ciphertext,
320 const char** cleartext,
327 gpgme_data_t gCiphertext, gPlaintext;
335 err = gpgme_new (&ctx);
336 gpgme_set_protocol (ctx, GPGMEPLUG_PROTOCOL);
338 gpgme_set_armor (ctx, cipherIsBinary ? 0 : 1);
344 gpgme_data_new_from_mem( &gCiphertext,
348 : strlen( ciphertext ),
351 gpgme_data_new( &gPlaintext );
353 err = gpgme_op_decrypt( ctx, gCiphertext, gPlaintext );
355 fprintf( stderr,
"\ngpgme_op_decrypt() returned this error code: %i\n\n", err );
359 const char* _errTxt = gpgme_strerror( err );
360 *errTxt = (
char*)malloc( strlen( _errTxt ) + 1 );
362 strcpy(*errTxt, _errTxt );
366 gpgme_data_release( gCiphertext );
368 rCiph = gpgme_data_release_and_get_mem( gPlaintext, &rCLen );
370 *cleartext = (
char*)malloc( rCLen + 1 );
374 strncpy((
char*)*cleartext, rCiph, rCLen );
376 ((
char*)(*cleartext))[rCLen] = 0;
380 gpgme_release( ctx );
386 trim_trailing_spaces(
char *
string )
390 for( mark = NULL, p =
string; *p; p++ ) {
391 if( isspace( *p ) ) {
407 static const unsigned char *
408 parse_dn_part (CryptPlug::DnPair *array,
const unsigned char *
string)
410 const unsigned char *s, *s1;
415 for (s =
string+1; *s && *s !=
'='; s++)
422 p = (
char*)xmalloc (n+1);
425 memcpy (p,
string, n);
427 trim_trailing_spaces ((
char*)p);
429 for (
unsigned int i = 0 ; i < numOidMaps ; ++i )
430 if ( !strcasecmp ((
char*)p, oidmap[i].oid) ) {
432 p = xstrdup (oidmap[i].name);
441 for (s=
string; hexdigitp (s); s++)
447 array->value = p = (
char*)xmalloc (n+1);
450 for (s1=
string; n; s1 += 2, n--)
456 for (n=0, s=
string; *s; s++)
461 if (*s ==
',' || *s ==
'=' || *s ==
'+'
462 || *s ==
'<' || *s ==
'>' || *s ==
'#' || *s ==
';'
463 || *s ==
'\\' || *s ==
'\"' || *s ==
' ')
465 else if (hexdigitp (s) && hexdigitp (s+1))
475 else if (*s ==
',' || *s ==
'=' || *s ==
'+'
476 || *s ==
'<' || *s ==
'>' || *s ==
'#' || *s ==
';' )
482 array->value = p = (
char*)xmalloc (n+1);
485 for (s=
string; n; s++, n--)
510 static CryptPlug::DnPair *
511 parse_dn (
const unsigned char *
string)
513 struct CryptPlug::DnPair *array;
514 size_t arrayidx, arraysize;
521 array = (CryptPlug::DnPair*)xmalloc ((arraysize+1) *
sizeof *array);
526 while (*
string ==
' ')
530 if (arrayidx >= arraysize)
532 struct CryptPlug::DnPair *a2;
535 a2 = (CryptPlug::DnPair*)xmalloc ((arraysize+1) *
sizeof *array);
536 for (
unsigned int i=0; i < arrayidx; i++)
538 a2[i].key = array[i].key;
539 a2[i].value = array[i].value;
544 array[arrayidx].key = NULL;
545 array[arrayidx].value = NULL;
546 string = parse_dn_part (array+arrayidx,
string);
550 while (*
string ==
' ')
552 if (*
string && *
string !=
',' && *
string !=
';' && *
string !=
'+')
557 array[arrayidx].key = NULL;
558 array[arrayidx].value = NULL;
562 for (
unsigned i=0; i < arrayidx; i++)
565 free (array[i].value);
572 add_dn_part( TQCString& result,
struct CryptPlug::DnPair& dnPair )
575 TQCString mappedPart( dnPair.key );
576 for (
unsigned int i = 0 ; i < numOidMaps ; ++i ){
577 if( !strcasecmp( dnPair.key, oidmap[i].oid ) ) {
578 mappedPart = oidmap[i].name;
582 result.append( mappedPart );
583 result.append(
"=" );
584 result.append( dnPair.value );
588 add_dn_parts( TQCString& result,
struct CryptPlug::DnPair* dn,
const char* part )
593 for(; dn->key; ++dn ) {
594 if( !strcmp( dn->key, part ) ) {
596 result.append(
"," );
597 add_dn_part( result, *dn );
606 reorder_dn(
struct CryptPlug::DnPair *dn,
607 char** attrOrder = 0,
608 const char* unknownAttrsHandling = 0 )
610 struct CryptPlug::DnPair *dnOrg = dn;
613 const char* defaultpart[] = {
614 "CN",
"S",
"SN",
"GN",
"T",
"UID",
615 "MAIL",
"EMAIL",
"MOBILE",
"TEL",
"FAX",
"STREET",
616 "L",
"PC",
"SP",
"ST",
622 const char** stdpart = attrOrder ? ((
const char**)attrOrder) : defaultpart;
623 int any=0, any2=0, found_X_=0, i;
625 TQCString resultUnknowns;
629 for(; dn->key; ++dn ) {
630 for( i = 0; stdpart[i]; ++i ) {
631 if( !strcmp( dn->key, stdpart[i] ) ) {
637 resultUnknowns.append(
"," );
638 add_dn_part( resultUnknowns, *dn );
646 if( unknownAttrsHandling &&
647 !strcmp(unknownAttrsHandling,
"PREFIX")
648 && *resultUnknowns ){
649 result.append( resultUnknowns );
656 for( i = 0; stdpart[i]; ++i ) {
659 result.append(
"," );
662 !strcmp(stdpart[i],
"_X_") &&
663 unknownAttrsHandling &&
664 !strcmp(unknownAttrsHandling,
"INFIX") ){
665 if ( !resultUnknowns.isEmpty() ) {
666 result.append( resultUnknowns );
671 any = add_dn_parts( result, dn, stdpart[i] );
676 if( !unknownAttrsHandling ||
677 !strcmp(unknownAttrsHandling,
"POSTFIX") ||
678 ( !strcmp(unknownAttrsHandling,
"INFIX") && !found_X_ ) ){
679 if( !resultUnknowns.isEmpty() ) {
681 result.append(
"," );
683 result.append( resultUnknowns );
687 char* cResult = (
char*)xmalloc( (result.length()+1)*
sizeof(char) );
688 if( result.isEmpty() )
691 strcpy( cResult, result );
695 GpgME::ImportResult CryptPlug::importCertificateFromMem(
const char* data,
size_t length )
697 using namespace GpgME;
699 std::unique_ptr<Context> context( Context::createForProtocol( mProtocol ) );
701 return ImportResult();
703 Data keydata( data, length,
false );
704 if ( keydata.isNull() )
705 return ImportResult();
707 return context->importKeys( keydata );
718 static gpgme_sig_stat_t
719 sig_stat_from_status( gpgme_error_t err )
721 switch ( gpg_err_code(err) ) {
722 case GPG_ERR_NO_ERROR:
723 return GPGME_SIG_STAT_GOOD;
724 case GPG_ERR_BAD_SIGNATURE:
725 return GPGME_SIG_STAT_BAD;
726 case GPG_ERR_NO_PUBKEY:
727 return GPGME_SIG_STAT_NOKEY;
728 case GPG_ERR_NO_DATA:
729 return GPGME_SIG_STAT_NOSIG;
730 case GPG_ERR_SIG_EXPIRED:
731 return GPGME_SIG_STAT_GOOD_EXP;
732 case GPG_ERR_KEY_EXPIRED:
733 return GPGME_SIG_STAT_GOOD_EXPKEY;
735 return GPGME_SIG_STAT_ERROR;
740 static gpgme_sig_stat_t
741 intersect_stati( gpgme_signature_t first )
744 return GPGME_SIG_STAT_NONE;
745 gpgme_sig_stat_t result = sig_stat_from_status( first->status );
746 for ( gpgme_signature_t sig = first->next ; sig ; sig = sig->next )
747 if ( sig_stat_from_status( sig->status ) != result )
748 return GPGME_SIG_STAT_DIFF;
753 sig_status_to_string( gpgme_sig_stat_t status )
758 case GPGME_SIG_STAT_NONE:
759 result =
"Oops: Signature not verified";
761 case GPGME_SIG_STAT_NOSIG:
762 result =
"No signature found";
764 case GPGME_SIG_STAT_GOOD:
765 result =
"Good signature";
767 case GPGME_SIG_STAT_BAD:
768 result =
"BAD signature";
770 case GPGME_SIG_STAT_NOKEY:
771 result =
"No public key to verify the signature";
773 case GPGME_SIG_STAT_ERROR:
774 result =
"Error verifying the signature";
776 case GPGME_SIG_STAT_DIFF:
777 result =
"Different results for signatures";
780 result =
"Error: Unknown status";
790 void obtain_signature_information( gpgme_ctx_t ctx,
791 gpgme_sig_stat_t & overallStatus,
792 struct CryptPlug::SignatureMetaData* sigmeta,
794 const char* unknownAttrsHandling,
795 bool * signatureFound=0 )
798 unsigned long sumGPGME;
799 SigStatusFlags sumPlug;
800 struct CryptPlug::DnPair* a;
806 sigmeta->extended_info = 0;
807 gpgme_verify_result_t result = gpgme_op_verify_result( ctx );
810 for ( gpgme_signature_t signature = result->signatures ; signature ; signature = signature->next, ++sig_idx ) {
811 void* alloc_return = realloc( sigmeta->extended_info,
812 sizeof( CryptPlug::SignatureMetaDataExtendedInfo )
816 sigmeta->extended_info = (CryptPlug::SignatureMetaDataExtendedInfo*)alloc_return;
819 CryptPlug::SignatureMetaDataExtendedInfo & this_info = sigmeta->extended_info[sig_idx];
822 memset( &this_info, 0,
sizeof (CryptPlug::SignatureMetaDataExtendedInfo) );
825 if ( signature->timestamp ) {
826 this_info.creation_time = (tm*)malloc(
sizeof(
struct tm ) );
827 if ( this_info.creation_time ) {
828 struct tm * ctime_val = localtime( (time_t*)&signature->timestamp );
829 memcpy( this_info.creation_time,
830 ctime_val,
sizeof(
struct tm ) );
835 sumGPGME = signature->summary;
836 fprintf( stderr,
"gpgmeplug checkMessageSignature status flags: %lX\n", sumGPGME );
839 #define convert(X) if ( sumGPGME & GPGME_SIGSUM_##X ) sumPlug |= SigStat_##X
843 convert(KEY_REVOKED);
844 convert(KEY_EXPIRED);
845 convert(SIG_EXPIRED);
846 convert(KEY_MISSING);
847 convert(CRL_MISSING);
848 convert(CRL_TOO_OLD);
852 if( sumGPGME && !sumPlug )
853 sumPlug = SigStat_NUMERICAL_CODE | sumGPGME;
854 this_info.sigStatusFlags = sumPlug;
857 if ( signature->fpr )
858 storeNewCharPtr( &this_info.fingerprint, signature->fpr );
861 this_info.validity = GPGME_VALIDITY_UNKNOWN;
867 err = gpgme_get_sig_key (ctx, sig_idx, &key);
870 const char* attr_string;
871 unsigned long attr_ulong;
874 attr_string = key->subkeys ? key->subkeys->keyid : 0 ;
876 storeNewCharPtr( &this_info.keyid, attr_string );
879 attr_string = key->subkeys ? gpgme_pubkey_algo_name( key->subkeys->pubkey_algo ) : 0 ;
880 if (attr_string != 0)
881 storeNewCharPtr( &this_info.algo, attr_string );
882 attr_ulong = key->subkeys ? key->subkeys->pubkey_algo : 0 ;
883 this_info.algo_num = attr_ulong;
886 attr_ulong = key->uids ? key->uids->validity : 0 ;
887 this_info.validity = attr_ulong;
892 attr_string = key->uids ? key->uids->uid : 0 ;
893 if (attr_string != 0) {
894 a = parse_dn( (
const unsigned char*)attr_string );
895 this_info.userid = reorder_dn( a, attrOrder, unknownAttrsHandling );
899 this_info.userid_num = attr_ulong;
902 this_info.keylen = key->subkeys ? key->subkeys->length : 0 ;
905 attr_ulong = key->subkeys ? key->subkeys->timestamp : 0 ;
906 this_info.key_created = attr_ulong;
909 attr_ulong = key->subkeys ? key->subkeys->expires : 0 ;
910 this_info.key_expires = attr_ulong;
913 attr_string = key->uids ? key->uids->name : 0 ;
914 if (attr_string != 0) {
915 a = parse_dn( (
const unsigned char*)attr_string );
916 this_info.name = reorder_dn( a, attrOrder, unknownAttrsHandling );
920 this_info.emailCount = 0;
921 this_info.emailList = 0;
922 for ( gpgme_user_id_t uid = key->uids ; uid ; uid = uid->next ) {
923 attr_string = uid->email;
924 if ( attr_string && *attr_string) {
925 fprintf( stderr,
"gpgmeplug checkMessageSignature found email: %s\n", attr_string );
926 if( !this_info.emailCount )
927 alloc_return = malloc(
sizeof(
char*) );
929 alloc_return = realloc( this_info.emailList,
931 * (this_info.emailCount + 1) );
933 this_info.emailList = (
char**)alloc_return;
934 storeNewCharPtr( &( this_info.emailList[ this_info.emailCount ] ),
936 ++this_info.emailCount;
940 if( !this_info.emailCount )
941 fprintf( stderr,
"gpgmeplug checkMessageSignature found NO EMAIL\n" );
944 attr_string = key->uids ? key->uids->comment : 0 ;
945 if (attr_string != 0)
946 storeNewCharPtr( &this_info.comment, attr_string );
949 gpgme_sig_stat_t status = sig_stat_from_status( signature->status );
950 const char* sig_status = sig_status_to_string( status );
951 storeNewCharPtr( &this_info.status_text, sig_status );
953 sigmeta->extended_info_count = sig_idx;
954 overallStatus = intersect_stati( result->signatures );
955 sigmeta->status_code = overallStatus;
956 storeNewCharPtr( &sigmeta->status, sig_status_to_string( overallStatus ) );
957 if ( signatureFound )
958 *signatureFound = ( overallStatus != GPGME_SIG_STAT_NONE );
961 bool CryptPlug::checkMessageSignature(
char** cleartext,
962 const char* signaturetext,
963 bool signatureIsBinary,
965 struct CryptPlug::SignatureMetaData* sigmeta,
967 const char* unknownAttrsHandling )
970 gpgme_sig_stat_t status = GPGME_SIG_STAT_NONE;
971 gpgme_data_t datapart, sigpart;
978 storeNewCharPtr( &sigmeta->status,
979 __GPGMEPLUG_ERROR_CLEARTEXT_IS_ZERO );
984 isOpaqueSigned = !*cleartext;
987 gpgme_set_protocol (ctx, GPGMEPLUG_PROTOCOL);
988 gpgme_set_armor (ctx, signatureIsBinary ? 0 : 1);
992 gpgme_data_new( &datapart );
994 gpgme_data_new_from_mem( &datapart, *cleartext,
995 strlen( *cleartext ), 1 );
997 gpgme_data_new_from_mem( &sigpart,
1001 : strlen( signaturetext ),
1004 if ( isOpaqueSigned )
1005 gpgme_op_verify( ctx, sigpart, 0, datapart );
1007 gpgme_op_verify( ctx, sigpart, datapart, 0 );
1009 if( isOpaqueSigned ) {
1010 rClear = gpgme_data_release_and_get_mem( datapart, &clearLen );
1011 *cleartext = (
char*)malloc( clearLen + 1 );
1014 strncpy(*cleartext, rClear, clearLen );
1015 (*cleartext)[clearLen] =
'\0';
1020 gpgme_data_release( datapart );
1022 gpgme_data_release( sigpart );
1024 obtain_signature_information( ctx, status, sigmeta,
1025 attrOrder, unknownAttrsHandling );
1027 gpgme_release( ctx );
1028 return ( status == GPGME_SIG_STAT_GOOD );
1031 bool CryptPlug::decryptAndCheckMessage(
const char* ciphertext,
1032 bool cipherIsBinary,
1034 const char** cleartext,
1036 bool* signatureFound,
1037 struct CryptPlug::SignatureMetaData* sigmeta,
1041 const char* unknownAttrsHandling )
1045 gpgme_decrypt_result_t decryptresult;
1046 gpgme_data_t gCiphertext, gPlaintext;
1047 gpgme_sig_stat_t sigstatus = GPGME_SIG_STAT_NONE;
1055 err = gpgme_new (&ctx);
1056 gpgme_set_protocol (ctx, GPGMEPLUG_PROTOCOL);
1058 gpgme_set_armor (ctx, cipherIsBinary ? 0 : 1);
1064 gpgme_data_new_from_mem( &gCiphertext,
1068 : strlen( ciphertext ),
1071 gpgme_data_new( &gPlaintext );
1073 err = gpgme_op_decrypt_verify( ctx, gCiphertext, gPlaintext );
1074 gpgme_data_release( gCiphertext );
1077 fprintf( stderr,
"\ngpgme_op_decrypt_verify() returned this error code: %i\n\n", err );
1081 const char* _errTxt = gpgme_strerror( err );
1082 *errTxt = (
char*)malloc( strlen( _errTxt ) + 1 );
1084 strcpy(*errTxt, _errTxt );
1086 gpgme_data_release( gPlaintext );
1087 gpgme_release( ctx );
1090 decryptresult = gpgme_op_decrypt_result( ctx );
1092 bool bWrongKeyUsage =
false;
1093 #ifdef HAVE_GPGME_WRONG_KEY_USAGE
1094 if( decryptresult && decryptresult->wrong_key_usage )
1095 bWrongKeyUsage =
true;
1098 if( bWrongKeyUsage ) {
1100 *errId = CRYPTPLUG_ERR_WRONG_KEY_USAGE;
1103 rCiph = gpgme_data_release_and_get_mem( gPlaintext, &rCLen );
1105 *cleartext = (
char*)malloc( rCLen + 1 );
1109 strncpy((
char*)*cleartext, rCiph, rCLen );
1111 ((
char*)(*cleartext))[rCLen] = 0;
1115 obtain_signature_information( ctx, sigstatus, sigmeta,
1116 attrOrder, unknownAttrsHandling,
1119 gpgme_release( ctx );
Common API header for CRYPTPLUG.