31 #include "kleo/oidmap.h" 33 #include <gpgmepp/context.h> 34 #include <gpgmepp/data.h> 35 #include <gpgmepp/importresult.h> 71 #define __GPGMEPLUG_ERROR_CLEARTEXT_IS_ZERO "Error: Cannot run checkMessageSignature() with cleartext == 0" 78 #ifndef GPGMEPLUG_ENCSIGN_MAKE_MIME_OBJECT 79 #define GPGMEPLUG_ENCSIGN_INCLUDE_CLEARTEXT false 80 #define GPGMEPLUG_ENCSIGN_MAKE_MIME_OBJECT false 81 #define GPGMEPLUG_ENCSIGN_MAKE_MULTI_MIME false 82 #define GPGMEPLUG_ENCSIGN_CTYPE_MAIN "" 83 #define GPGMEPLUG_ENCSIGN_CDISP_MAIN "" 84 #define GPGMEPLUG_ENCSIGN_CTENC_MAIN "" 85 #define GPGMEPLUG_ENCSIGN_CTYPE_VERSION "" 86 #define GPGMEPLUG_ENCSIGN_CDISP_VERSION "" 87 #define GPGMEPLUG_ENCSIGN_CTENC_VERSION "" 88 #define GPGMEPLUG_ENCSIGN_BTEXT_VERSION "" 89 #define GPGMEPLUG_ENCSIGN_CTYPE_CODE "" 90 #define GPGMEPLUG_ENCSIGN_CDISP_CODE "" 91 #define GPGMEPLUG_ENCSIGN_CTENC_CODE "" 92 #define GPGMEPLUG_ENCSIGN_FLAT_PREFIX "" 93 #define GPGMEPLUG_ENCSIGN_FLAT_SEPARATOR "" 94 #define GPGMEPLUG_ENCSIGN_FLAT_POSTFIX "" 100 SMIMECryptPlug::SMIMECryptPlug() : CryptPlug() {
101 GPGMEPLUG_PROTOCOL = GPGME_PROTOCOL_CMS;
102 mProtocol = GpgME::Context::CMS;
106 GPGMEPLUG_OPA_SIGN_INCLUDE_CLEARTEXT =
false;
107 GPGMEPLUG_OPA_SIGN_MAKE_MIME_OBJECT =
true;
108 GPGMEPLUG_OPA_SIGN_MAKE_MULTI_MIME =
false;
109 GPGMEPLUG_OPA_SIGN_CTYPE_MAIN =
"application/pkcs7-mime; smime-type=signed-data; name=\"smime.p7m\"";
110 GPGMEPLUG_OPA_SIGN_CDISP_MAIN =
"attachment; filename=\"smime.p7m\"";
111 GPGMEPLUG_OPA_SIGN_CTENC_MAIN =
"base64";
112 GPGMEPLUG_OPA_SIGN_CTYPE_VERSION =
"";
113 GPGMEPLUG_OPA_SIGN_CDISP_VERSION =
"";
114 GPGMEPLUG_OPA_SIGN_CTENC_VERSION =
"";
115 GPGMEPLUG_OPA_SIGN_BTEXT_VERSION =
"";
116 GPGMEPLUG_OPA_SIGN_CTYPE_CODE =
"";
117 GPGMEPLUG_OPA_SIGN_CDISP_CODE =
"";
118 GPGMEPLUG_OPA_SIGN_CTENC_CODE =
"";
119 GPGMEPLUG_OPA_SIGN_FLAT_PREFIX =
"";
120 GPGMEPLUG_OPA_SIGN_FLAT_SEPARATOR =
"";
121 GPGMEPLUG_OPA_SIGN_FLAT_POSTFIX =
"";
123 GPGMEPLUG_DET_SIGN_INCLUDE_CLEARTEXT =
true;
124 GPGMEPLUG_DET_SIGN_MAKE_MIME_OBJECT =
true;
125 GPGMEPLUG_DET_SIGN_MAKE_MULTI_MIME =
true;
126 GPGMEPLUG_DET_SIGN_CTYPE_MAIN =
"multipart/signed; protocol=\"application/pkcs7-signature\"; micalg=sha1";
127 GPGMEPLUG_DET_SIGN_CDISP_MAIN =
"";
128 GPGMEPLUG_DET_SIGN_CTENC_MAIN =
"";
129 GPGMEPLUG_DET_SIGN_CTYPE_VERSION =
"";
130 GPGMEPLUG_DET_SIGN_CDISP_VERSION =
"";
131 GPGMEPLUG_DET_SIGN_CTENC_VERSION =
"";
132 GPGMEPLUG_DET_SIGN_BTEXT_VERSION =
"";
133 GPGMEPLUG_DET_SIGN_CTYPE_CODE =
"application/pkcs7-signature; name=\"smime.p7s\"";
134 GPGMEPLUG_DET_SIGN_CDISP_CODE =
"attachment; filename=\"smime.p7s\"";
135 GPGMEPLUG_DET_SIGN_CTENC_CODE =
"base64";
136 GPGMEPLUG_DET_SIGN_FLAT_PREFIX =
"";
137 GPGMEPLUG_DET_SIGN_FLAT_SEPARATOR =
"";
138 GPGMEPLUG_DET_SIGN_FLAT_POSTFIX =
"";
140 __GPGMEPLUG_SIGNATURE_CODE_IS_BINARY =
true;
143 GPGMEPLUG_ENC_INCLUDE_CLEARTEXT =
false;
144 GPGMEPLUG_ENC_MAKE_MIME_OBJECT =
true;
145 GPGMEPLUG_ENC_MAKE_MULTI_MIME =
false;
146 GPGMEPLUG_ENC_CTYPE_MAIN =
"application/pkcs7-mime; smime-type=enveloped-data; name=\"smime.p7m\"";
147 GPGMEPLUG_ENC_CDISP_MAIN =
"attachment; filename=\"smime.p7m\"";
148 GPGMEPLUG_ENC_CTENC_MAIN =
"base64";
149 GPGMEPLUG_ENC_CTYPE_VERSION =
"";
150 GPGMEPLUG_ENC_CDISP_VERSION =
"";
151 GPGMEPLUG_ENC_CTENC_VERSION =
"";
152 GPGMEPLUG_ENC_BTEXT_VERSION =
"";
153 GPGMEPLUG_ENC_CTYPE_CODE =
"";
154 GPGMEPLUG_ENC_CDISP_CODE =
"";
155 GPGMEPLUG_ENC_CTENC_CODE =
"";
156 GPGMEPLUG_ENC_FLAT_PREFIX =
"";
157 GPGMEPLUG_ENC_FLAT_SEPARATOR =
"";
158 GPGMEPLUG_ENC_FLAT_POSTFIX =
"";
159 __GPGMEPLUG_ENCRYPTED_CODE_IS_BINARY =
true;
162 OpenPGPCryptPlug::OpenPGPCryptPlug() : CryptPlug() {
163 GPGMEPLUG_PROTOCOL = GPGME_PROTOCOL_OpenPGP;
164 mProtocol = GpgME::Context::OpenPGP;
168 GPGMEPLUG_OPA_SIGN_INCLUDE_CLEARTEXT =
false;
169 GPGMEPLUG_OPA_SIGN_MAKE_MIME_OBJECT =
false;
170 GPGMEPLUG_OPA_SIGN_MAKE_MULTI_MIME =
false;
171 GPGMEPLUG_OPA_SIGN_CTYPE_MAIN =
"";
172 GPGMEPLUG_OPA_SIGN_CDISP_MAIN =
"";
173 GPGMEPLUG_OPA_SIGN_CTENC_MAIN =
"";
174 GPGMEPLUG_OPA_SIGN_CTYPE_VERSION =
"";
175 GPGMEPLUG_OPA_SIGN_CDISP_VERSION =
"";
176 GPGMEPLUG_OPA_SIGN_CTENC_VERSION =
"";
177 GPGMEPLUG_OPA_SIGN_BTEXT_VERSION =
"";
178 GPGMEPLUG_OPA_SIGN_CTYPE_CODE =
"";
179 GPGMEPLUG_OPA_SIGN_CDISP_CODE =
"";
180 GPGMEPLUG_OPA_SIGN_CTENC_CODE =
"";
181 GPGMEPLUG_OPA_SIGN_FLAT_PREFIX =
"";
182 GPGMEPLUG_OPA_SIGN_FLAT_SEPARATOR =
"";
183 GPGMEPLUG_OPA_SIGN_FLAT_POSTFIX =
"";
185 GPGMEPLUG_DET_SIGN_INCLUDE_CLEARTEXT =
true;
186 GPGMEPLUG_DET_SIGN_MAKE_MIME_OBJECT =
true;
187 GPGMEPLUG_DET_SIGN_MAKE_MULTI_MIME =
true;
188 GPGMEPLUG_DET_SIGN_CTYPE_MAIN =
"multipart/signed; protocol=\"application/pgp-signature\"; micalg=pgp-sha1";
189 GPGMEPLUG_DET_SIGN_CDISP_MAIN =
"";
190 GPGMEPLUG_DET_SIGN_CTENC_MAIN =
"";
191 GPGMEPLUG_DET_SIGN_CTYPE_VERSION =
"";
192 GPGMEPLUG_DET_SIGN_CDISP_VERSION =
"";
193 GPGMEPLUG_DET_SIGN_CTENC_VERSION =
"";
194 GPGMEPLUG_DET_SIGN_BTEXT_VERSION =
"";
195 GPGMEPLUG_DET_SIGN_CTYPE_CODE =
"application/pgp-signature";
196 GPGMEPLUG_DET_SIGN_CDISP_CODE =
"";
197 GPGMEPLUG_DET_SIGN_CTENC_CODE =
"";
198 GPGMEPLUG_DET_SIGN_FLAT_PREFIX =
"";
199 GPGMEPLUG_DET_SIGN_FLAT_SEPARATOR =
"";
200 GPGMEPLUG_DET_SIGN_FLAT_POSTFIX =
"";
202 __GPGMEPLUG_SIGNATURE_CODE_IS_BINARY =
false;
205 GPGMEPLUG_ENC_INCLUDE_CLEARTEXT =
false;
206 GPGMEPLUG_ENC_MAKE_MIME_OBJECT =
true;
207 GPGMEPLUG_ENC_MAKE_MULTI_MIME =
true;
208 GPGMEPLUG_ENC_CTYPE_MAIN =
"multipart/encrypted; protocol=\"application/pgp-encrypted\"";
209 GPGMEPLUG_ENC_CDISP_MAIN =
"";
210 GPGMEPLUG_ENC_CTENC_MAIN =
"";
211 GPGMEPLUG_ENC_CTYPE_VERSION =
"application/pgp-encrypted";
212 GPGMEPLUG_ENC_CDISP_VERSION =
"attachment";
213 GPGMEPLUG_ENC_CTENC_VERSION =
"";
214 GPGMEPLUG_ENC_BTEXT_VERSION =
"Version: 1";
215 GPGMEPLUG_ENC_CTYPE_CODE =
"application/octet-stream";
216 GPGMEPLUG_ENC_CDISP_CODE =
"inline; filename=\"msg.asc\"";
217 GPGMEPLUG_ENC_CTENC_CODE =
"";
218 GPGMEPLUG_ENC_FLAT_PREFIX =
"";
219 GPGMEPLUG_ENC_FLAT_SEPARATOR =
"";
220 GPGMEPLUG_ENC_FLAT_POSTFIX =
"";
221 __GPGMEPLUG_ENCRYPTED_CODE_IS_BINARY =
false;
224 #define days_from_seconds(x) ((x)/86400) 227 #define MAX_GPGME_IDX 20 230 #define spacep(p) (*(p) == ' ' || *(p) == '\t') 231 #define digitp(p) (*(p) >= '0' && *(p) <= '9') 232 #define hexdigitp(a) (digitp (a) \ 233 || (*(a) >= 'A' && *(a) <= 'F') \ 234 || (*(a) >= 'a' && *(a) <= 'f')) 236 #define atoi_1(p) (*(p) - '0' ) 237 #define atoi_2(p) ((atoi_1(p) * 10) + atoi_1((p)+1)) 238 #define atoi_4(p) ((atoi_2(p) * 100) + atoi_2((p)+2)) 239 #define xtoi_1(p) (*(p) <= '9'? (*(p)- '0'): \ 240 *(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10)) 241 #define xtoi_2(p) ((xtoi_1(p) * 16) + xtoi_1((p)+1)) 246 void *p = malloc (n);
249 fputs (
"\nfatal: out of core\n", stderr);
259 xstrdup (
const char *
string)
261 char *p = (
char*)xmalloc (strlen (
string)+1);
267 CryptPlug::CryptPlug() {
270 CryptPlug::~CryptPlug() {
273 bool CryptPlug::initialize() {
274 GpgME::setDefaultLocale( LC_CTYPE, setlocale( LC_CTYPE, 0 ) );
275 GpgME::setDefaultLocale( LC_MESSAGES, setlocale( LC_MESSAGES, 0 ) );
276 return (gpgme_engine_check_version (GPGMEPLUG_PROTOCOL) == GPG_ERR_NO_ERROR);
280 bool CryptPlug::hasFeature( Feature flag )
284 case Feature_SignMessages:
285 case Feature_VerifySignatures:
286 case Feature_EncryptMessages:
287 case Feature_DecryptMessages:
288 case Feature_SendCertificates:
289 case Feature_PinEntrySettings:
290 case Feature_StoreMessagesWithSigs:
291 case Feature_EncryptionCRLs:
292 case Feature_StoreMessagesEncrypted:
293 case Feature_CheckCertificatePath:
295 case Feature_WarnSignCertificateExpiry:
296 case Feature_WarnSignEmailNotInCertificate:
297 case Feature_WarnEncryptCertificateExpiry:
298 case Feature_WarnEncryptEmailNotInCertificate:
299 return GPGMEPLUG_PROTOCOL == GPGME_PROTOCOL_CMS;
301 case Feature_CRLDirectoryService:
302 case Feature_CertificateDirectoryService:
311 void storeNewCharPtr(
char** dest,
const char* src )
313 int sLen = strlen( src );
314 *dest = (
char*)xmalloc( sLen + 1 );
315 strcpy( *dest, src );
318 bool CryptPlug::decryptMessage(
const char* ciphertext,
321 const char** cleartext,
328 gpgme_data_t gCiphertext, gPlaintext;
336 err = gpgme_new (&ctx);
337 gpgme_set_protocol (ctx, GPGMEPLUG_PROTOCOL);
339 gpgme_set_armor (ctx, cipherIsBinary ? 0 : 1);
345 gpgme_data_new_from_mem( &gCiphertext,
349 : strlen( ciphertext ),
352 gpgme_data_new( &gPlaintext );
354 err = gpgme_op_decrypt( ctx, gCiphertext, gPlaintext );
356 fprintf( stderr,
"\ngpgme_op_decrypt() returned this error code: %i\n\n", err );
360 const char* _errTxt = gpgme_strerror( err );
361 *errTxt = (
char*)malloc( strlen( _errTxt ) + 1 );
363 strcpy(*errTxt, _errTxt );
367 gpgme_data_release( gCiphertext );
369 rCiph = gpgme_data_release_and_get_mem( gPlaintext, &rCLen );
371 *cleartext = (
char*)malloc( rCLen + 1 );
375 strncpy((
char*)*cleartext, rCiph, rCLen );
377 ((
char*)(*cleartext))[rCLen] = 0;
381 gpgme_release( ctx );
387 trim_trailing_spaces(
char *
string )
391 for( mark = NULL, p =
string; *p; p++ ) {
392 if( isspace( *p ) ) {
408 static const unsigned char *
409 parse_dn_part (CryptPlug::DnPair *array,
const unsigned char *
string)
411 const unsigned char *s, *s1;
416 for (s =
string+1; *s && *s !=
'='; s++)
423 p = (
char*)xmalloc (n+1);
426 memcpy (p,
string, n);
428 trim_trailing_spaces ((
char*)p);
430 for (
unsigned int i = 0 ; i < numOidMaps ; ++i )
431 if ( !strcasecmp ((
char*)p, oidmap[i].oid) ) {
433 p = xstrdup (oidmap[i].name);
442 for (s=
string; hexdigitp (s); s++)
448 array->value = p = (
char*)xmalloc (n+1);
451 for (s1=
string; n; s1 += 2, n--)
457 for (n=0, s=
string; *s; s++)
462 if (*s ==
',' || *s ==
'=' || *s ==
'+' 463 || *s ==
'<' || *s ==
'>' || *s ==
'#' || *s ==
';' 464 || *s ==
'\\' || *s ==
'\"' || *s ==
' ')
466 else if (hexdigitp (s) && hexdigitp (s+1))
476 else if (*s ==
',' || *s ==
'=' || *s ==
'+' 477 || *s ==
'<' || *s ==
'>' || *s ==
'#' || *s ==
';' )
483 array->value = p = (
char*)xmalloc (n+1);
486 for (s=
string; n; s++, n--)
511 static CryptPlug::DnPair *
512 parse_dn (
const unsigned char *
string)
514 struct CryptPlug::DnPair *array;
515 size_t arrayidx, arraysize;
522 array = (CryptPlug::DnPair*)xmalloc ((arraysize+1) *
sizeof *array);
527 while (*
string ==
' ')
531 if (arrayidx >= arraysize)
533 struct CryptPlug::DnPair *a2;
536 a2 = (CryptPlug::DnPair*)xmalloc ((arraysize+1) *
sizeof *array);
537 for (
unsigned int i=0; i < arrayidx; i++)
539 a2[i].key = array[i].key;
540 a2[i].value = array[i].value;
545 array[arrayidx].key = NULL;
546 array[arrayidx].value = NULL;
547 string = parse_dn_part (array+arrayidx,
string);
551 while (*
string ==
' ')
553 if (*
string && *
string !=
',' && *
string !=
';' && *
string !=
'+')
558 array[arrayidx].key = NULL;
559 array[arrayidx].value = NULL;
563 for (
unsigned i=0; i < arrayidx; i++)
566 free (array[i].value);
573 add_dn_part( TQCString& result,
struct CryptPlug::DnPair& dnPair )
576 TQCString mappedPart( dnPair.key );
577 for (
unsigned int i = 0 ; i < numOidMaps ; ++i ){
578 if( !strcasecmp( dnPair.key, oidmap[i].oid ) ) {
579 mappedPart = oidmap[i].name;
583 result.append( mappedPart );
584 result.append(
"=" );
585 result.append( dnPair.value );
589 add_dn_parts( TQCString& result,
struct CryptPlug::DnPair* dn,
const char* part )
594 for(; dn->key; ++dn ) {
595 if( !strcmp( dn->key, part ) ) {
597 result.append(
"," );
598 add_dn_part( result, *dn );
607 reorder_dn(
struct CryptPlug::DnPair *dn,
608 char** attrOrder = 0,
609 const char* unknownAttrsHandling = 0 )
611 struct CryptPlug::DnPair *dnOrg = dn;
614 const char* defaultpart[] = {
615 "CN",
"S",
"SN",
"GN",
"T",
"UID",
616 "MAIL",
"EMAIL",
"MOBILE",
"TEL",
"FAX",
"STREET",
617 "L",
"PC",
"SP",
"ST",
623 const char** stdpart = attrOrder ? ((
const char**)attrOrder) : defaultpart;
624 int any=0, any2=0, found_X_=0, i;
626 TQCString resultUnknowns;
630 for(; dn->key; ++dn ) {
631 for( i = 0; stdpart[i]; ++i ) {
632 if( !strcmp( dn->key, stdpart[i] ) ) {
638 resultUnknowns.append(
"," );
639 add_dn_part( resultUnknowns, *dn );
647 if( unknownAttrsHandling &&
648 !strcmp(unknownAttrsHandling,
"PREFIX")
649 && *resultUnknowns ){
650 result.append( resultUnknowns );
657 for( i = 0; stdpart[i]; ++i ) {
660 result.append(
"," );
663 !strcmp(stdpart[i],
"_X_") &&
664 unknownAttrsHandling &&
665 !strcmp(unknownAttrsHandling,
"INFIX") ){
666 if ( !resultUnknowns.isEmpty() ) {
667 result.append( resultUnknowns );
672 any = add_dn_parts( result, dn, stdpart[i] );
677 if( !unknownAttrsHandling ||
678 !strcmp(unknownAttrsHandling,
"POSTFIX") ||
679 ( !strcmp(unknownAttrsHandling,
"INFIX") && !found_X_ ) ){
680 if( !resultUnknowns.isEmpty() ) {
682 result.append(
"," );
684 result.append( resultUnknowns );
688 char* cResult = (
char*)xmalloc( (result.length()+1)*
sizeof(
char) );
689 if( result.isEmpty() )
692 strcpy( cResult, result );
696 GpgME::ImportResult CryptPlug::importCertificateFromMem(
const char* data,
size_t length )
698 using namespace GpgME;
700 std::auto_ptr<Context> context( Context::createForProtocol( mProtocol ) );
701 if ( !context.get() )
702 return ImportResult();
704 Data keydata( data, length,
false );
705 if ( keydata.isNull() )
706 return ImportResult();
708 return context->importKeys( keydata );
719 static gpgme_sig_stat_t
720 sig_stat_from_status( gpgme_error_t err )
722 switch ( gpg_err_code(err) ) {
723 case GPG_ERR_NO_ERROR:
724 return GPGME_SIG_STAT_GOOD;
725 case GPG_ERR_BAD_SIGNATURE:
726 return GPGME_SIG_STAT_BAD;
727 case GPG_ERR_NO_PUBKEY:
728 return GPGME_SIG_STAT_NOKEY;
729 case GPG_ERR_NO_DATA:
730 return GPGME_SIG_STAT_NOSIG;
731 case GPG_ERR_SIG_EXPIRED:
732 return GPGME_SIG_STAT_GOOD_EXP;
733 case GPG_ERR_KEY_EXPIRED:
734 return GPGME_SIG_STAT_GOOD_EXPKEY;
736 return GPGME_SIG_STAT_ERROR;
741 static gpgme_sig_stat_t
742 intersect_stati( gpgme_signature_t first )
745 return GPGME_SIG_STAT_NONE;
746 gpgme_sig_stat_t result = sig_stat_from_status( first->status );
747 for ( gpgme_signature_t sig = first->next ; sig ; sig = sig->next )
748 if ( sig_stat_from_status( sig->status ) != result )
749 return GPGME_SIG_STAT_DIFF;
754 sig_status_to_string( gpgme_sig_stat_t status )
759 case GPGME_SIG_STAT_NONE:
760 result =
"Oops: Signature not verified";
762 case GPGME_SIG_STAT_NOSIG:
763 result =
"No signature found";
765 case GPGME_SIG_STAT_GOOD:
766 result =
"Good signature";
768 case GPGME_SIG_STAT_BAD:
769 result =
"BAD signature";
771 case GPGME_SIG_STAT_NOKEY:
772 result =
"No public key to verify the signature";
774 case GPGME_SIG_STAT_ERROR:
775 result =
"Error verifying the signature";
777 case GPGME_SIG_STAT_DIFF:
778 result =
"Different results for signatures";
781 result =
"Error: Unknown status";
791 void obtain_signature_information( gpgme_ctx_t ctx,
792 gpgme_sig_stat_t & overallStatus,
793 struct CryptPlug::SignatureMetaData* sigmeta,
795 const char* unknownAttrsHandling,
796 bool * signatureFound=0 )
799 unsigned long sumGPGME;
800 SigStatusFlags sumPlug;
801 struct CryptPlug::DnPair* a;
807 sigmeta->extended_info = 0;
808 gpgme_verify_result_t result = gpgme_op_verify_result( ctx );
811 for ( gpgme_signature_t signature = result->signatures ; signature ; signature = signature->next, ++sig_idx ) {
812 void* alloc_return = realloc( sigmeta->extended_info,
813 sizeof( CryptPlug::SignatureMetaDataExtendedInfo )
817 sigmeta->extended_info = (CryptPlug::SignatureMetaDataExtendedInfo*)alloc_return;
820 CryptPlug::SignatureMetaDataExtendedInfo & this_info = sigmeta->extended_info[sig_idx];
823 memset( &this_info, 0,
sizeof (CryptPlug::SignatureMetaDataExtendedInfo) );
826 if ( signature->timestamp ) {
827 this_info.creation_time = (tm*)malloc(
sizeof(
struct tm ) );
828 if ( this_info.creation_time ) {
829 struct tm * ctime_val = localtime( (time_t*)&signature->timestamp );
830 memcpy( this_info.creation_time,
831 ctime_val,
sizeof(
struct tm ) );
836 sumGPGME = signature->summary;
837 fprintf( stderr,
"gpgmeplug checkMessageSignature status flags: %lX\n", sumGPGME );
840 #define convert(X) if ( sumGPGME & GPGME_SIGSUM_##X ) sumPlug |= SigStat_##X 844 convert(KEY_REVOKED);
845 convert(KEY_EXPIRED);
846 convert(SIG_EXPIRED);
847 convert(KEY_MISSING);
848 convert(CRL_MISSING);
849 convert(CRL_TOO_OLD);
853 if( sumGPGME && !sumPlug )
854 sumPlug = SigStat_NUMERICAL_CODE | sumGPGME;
855 this_info.sigStatusFlags = sumPlug;
858 if ( signature->fpr )
859 storeNewCharPtr( &this_info.fingerprint, signature->fpr );
862 this_info.validity = GPGME_VALIDITY_UNKNOWN;
868 err = gpgme_get_sig_key (ctx, sig_idx, &key);
871 const char* attr_string;
872 unsigned long attr_ulong;
875 attr_string = key->subkeys ? key->subkeys->keyid : 0 ;
877 storeNewCharPtr( &this_info.keyid, attr_string );
880 attr_string = key->subkeys ? gpgme_pubkey_algo_name( key->subkeys->pubkey_algo ) : 0 ;
881 if (attr_string != 0)
882 storeNewCharPtr( &this_info.algo, attr_string );
883 attr_ulong = key->subkeys ? key->subkeys->pubkey_algo : 0 ;
884 this_info.algo_num = attr_ulong;
887 attr_ulong = key->uids ? key->uids->validity : 0 ;
888 this_info.validity = attr_ulong;
893 attr_string = key->uids ? key->uids->uid : 0 ;
894 if (attr_string != 0) {
895 a = parse_dn( (
const unsigned char*)attr_string );
896 this_info.userid = reorder_dn( a, attrOrder, unknownAttrsHandling );
900 this_info.userid_num = attr_ulong;
903 this_info.keylen = key->subkeys ? key->subkeys->length : 0 ;
906 attr_ulong = key->subkeys ? key->subkeys->timestamp : 0 ;
907 this_info.key_created = attr_ulong;
910 attr_ulong = key->subkeys ? key->subkeys->expires : 0 ;
911 this_info.key_expires = attr_ulong;
914 attr_string = key->uids ? key->uids->name : 0 ;
915 if (attr_string != 0) {
916 a = parse_dn( (
const unsigned char*)attr_string );
917 this_info.name = reorder_dn( a, attrOrder, unknownAttrsHandling );
921 this_info.emailCount = 0;
922 this_info.emailList = 0;
923 for ( gpgme_user_id_t uid = key->uids ; uid ; uid = uid->next ) {
924 attr_string = uid->email;
925 if ( attr_string && *attr_string) {
926 fprintf( stderr,
"gpgmeplug checkMessageSignature found email: %s\n", attr_string );
927 if( !this_info.emailCount )
928 alloc_return = malloc(
sizeof(
char*) );
930 alloc_return = realloc( this_info.emailList,
932 * (this_info.emailCount + 1) );
934 this_info.emailList = (
char**)alloc_return;
935 storeNewCharPtr( &( this_info.emailList[ this_info.emailCount ] ),
937 ++this_info.emailCount;
941 if( !this_info.emailCount )
942 fprintf( stderr,
"gpgmeplug checkMessageSignature found NO EMAIL\n" );
945 attr_string = key->uids ? key->uids->comment : 0 ;
946 if (attr_string != 0)
947 storeNewCharPtr( &this_info.comment, attr_string );
950 gpgme_sig_stat_t status = sig_stat_from_status( signature->status );
951 const char* sig_status = sig_status_to_string( status );
952 storeNewCharPtr( &this_info.status_text, sig_status );
954 sigmeta->extended_info_count = sig_idx;
955 overallStatus = intersect_stati( result->signatures );
956 sigmeta->status_code = overallStatus;
957 storeNewCharPtr( &sigmeta->status, sig_status_to_string( overallStatus ) );
958 if ( signatureFound )
959 *signatureFound = ( overallStatus != GPGME_SIG_STAT_NONE );
962 bool CryptPlug::checkMessageSignature(
char** cleartext,
963 const char* signaturetext,
964 bool signatureIsBinary,
966 struct CryptPlug::SignatureMetaData* sigmeta,
968 const char* unknownAttrsHandling )
971 gpgme_sig_stat_t status = GPGME_SIG_STAT_NONE;
972 gpgme_data_t datapart, sigpart;
979 storeNewCharPtr( &sigmeta->status,
980 __GPGMEPLUG_ERROR_CLEARTEXT_IS_ZERO );
985 isOpaqueSigned = !*cleartext;
988 gpgme_set_protocol (ctx, GPGMEPLUG_PROTOCOL);
989 gpgme_set_armor (ctx, signatureIsBinary ? 0 : 1);
993 gpgme_data_new( &datapart );
995 gpgme_data_new_from_mem( &datapart, *cleartext,
996 strlen( *cleartext ), 1 );
998 gpgme_data_new_from_mem( &sigpart,
1002 : strlen( signaturetext ),
1005 if ( isOpaqueSigned )
1006 gpgme_op_verify( ctx, sigpart, 0, datapart );
1008 gpgme_op_verify( ctx, sigpart, datapart, 0 );
1010 if( isOpaqueSigned ) {
1011 rClear = gpgme_data_release_and_get_mem( datapart, &clearLen );
1012 *cleartext = (
char*)malloc( clearLen + 1 );
1015 strncpy(*cleartext, rClear, clearLen );
1016 (*cleartext)[clearLen] =
'\0';
1021 gpgme_data_release( datapart );
1023 gpgme_data_release( sigpart );
1025 obtain_signature_information( ctx, status, sigmeta,
1026 attrOrder, unknownAttrsHandling );
1028 gpgme_release( ctx );
1029 return ( status == GPGME_SIG_STAT_GOOD );
1032 bool CryptPlug::decryptAndCheckMessage(
const char* ciphertext,
1033 bool cipherIsBinary,
1035 const char** cleartext,
1037 bool* signatureFound,
1038 struct CryptPlug::SignatureMetaData* sigmeta,
1042 const char* unknownAttrsHandling )
1046 gpgme_decrypt_result_t decryptresult;
1047 gpgme_data_t gCiphertext, gPlaintext;
1048 gpgme_sig_stat_t sigstatus = GPGME_SIG_STAT_NONE;
1056 err = gpgme_new (&ctx);
1057 gpgme_set_protocol (ctx, GPGMEPLUG_PROTOCOL);
1059 gpgme_set_armor (ctx, cipherIsBinary ? 0 : 1);
1065 gpgme_data_new_from_mem( &gCiphertext,
1069 : strlen( ciphertext ),
1072 gpgme_data_new( &gPlaintext );
1074 err = gpgme_op_decrypt_verify( ctx, gCiphertext, gPlaintext );
1075 gpgme_data_release( gCiphertext );
1078 fprintf( stderr,
"\ngpgme_op_decrypt_verify() returned this error code: %i\n\n", err );
1082 const char* _errTxt = gpgme_strerror( err );
1083 *errTxt = (
char*)malloc( strlen( _errTxt ) + 1 );
1085 strcpy(*errTxt, _errTxt );
1087 gpgme_data_release( gPlaintext );
1088 gpgme_release( ctx );
1091 decryptresult = gpgme_op_decrypt_result( ctx );
1093 bool bWrongKeyUsage =
false;
1094 #ifdef HAVE_GPGME_WRONG_KEY_USAGE 1095 if( decryptresult && decryptresult->wrong_key_usage )
1096 bWrongKeyUsage =
true;
1099 if( bWrongKeyUsage ) {
1101 *errId = CRYPTPLUG_ERR_WRONG_KEY_USAGE;
1104 rCiph = gpgme_data_release_and_get_mem( gPlaintext, &rCLen );
1106 *cleartext = (
char*)malloc( rCLen + 1 );
1110 strncpy((
char*)*cleartext, rCiph, rCLen );
1112 ((
char*)(*cleartext))[rCLen] = 0;
1116 obtain_signature_information( ctx, sigstatus, sigmeta,
1117 attrOrder, unknownAttrsHandling,
1120 gpgme_release( ctx );
Common API header for CRYPTPLUG.