1 /*
2 
3     File: file_gpg.c
4 
5     Copyright (C) 2008-2012 Christophe GRENIER <grenier@cgsecurity.org>
6 
7     This software is free software; you can redistribute it and/or modify
8     it under the terms of the GNU General Public License as published by
9     the Free Software Foundation; either version 2 of the License, or
10     (at your option) any later version.
11 
12     This program 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 General Public License for more details.
16 
17     You should have received a copy of the GNU General Public License along
18     with this program; if not, write the Free Software Foundation, Inc., 51
19     Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 
21  */
22 
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26 #ifdef HAVE_STRING_H
27 #include <string.h>
28 #endif
29 #include <stdio.h>
30 #include "types.h"
31 #include "common.h"
32 #include "filegen.h"
33 #ifdef DEBUG_GPG
34 #include "log.h"
35 #endif
36 
37 static void register_header_check_gpg(file_stat_t *file_stat);
38 static int header_check_gpg(const unsigned char *buffer, const unsigned int buffer_size, const unsigned int safe_header_only, const file_recovery_t *file_recovery, file_recovery_t *file_recovery_new);
39 
40 const file_hint_t file_hint_gpg= {
41   .extension="gpg",
42   .description="OpenPGP/GPG (Partial support)",
43   .max_filesize=PHOTOREC_MAX_FILE_SIZE,
44   .recover=1,
45   .enable_by_default=1,
46   .register_header_check=&register_header_check_gpg
47 };
48 
49 /* See rfc4880 OpenPGP Message Format */
50 
51 /* Public-Key Encrypted Session Key Packets */
52 #define OPENPGP_TAG_PUBKEY_ENC_SESSION_KEY	1
53 /* Signature Packet */
54 #define OPENPGP_TAG_SIGNATURE			2
55 /* Symmetric-Key Encrypted Session Key Packets */
56 #define OPENPGP_TAG_SYMKEY_ENC_SESSION_KEY	3
57 /* One-Pass Signature Packets (Tag 4) */
58 #define OPENPGP_TAG_ONE_PASS_SIG		4
59 /* Secret-Key Packet (Tag 5) */
60 #define OPENPGP_TAG_SEC_KEY			5
61 /* Public-Key Packet (Tag 6)*/
62 #define OPENPGP_TAG_PUB_KEY			6
63 /* Secret-Subkey Packet (Tag 7)	*/
64 #define OPENPGP_TAG_SEC_SUBKEY			7
65 /* Compressed Data Packet (Tag 8) */
66 /* Symmetrically Encrypted Data Packet */
67 #define OPENPGP_TAG_SYM_ENC_DATA		9
68 /* Marker Packet (Tag 10) */
69 #define OPENPGP_TAG_MARKER			10
70 /* Literal Data Packet (Tag 11)
71  * Trust Packet (Tag 12) */
72 #define OPENPGP_TAG_TRUST			12
73  /* User ID Packet */
74 #define OPENPGP_TAG_USER_ID			13
75  /* Public-Subkey Packet (Tag 14) */
76 #define OPENPGP_TAG_PUB_SUBKEY			14
77 /* User Attribute Packet (Tag 17)
78  */
79 /* Sym. Encrypted Integrity Protected Data Packet */
80 #define OPENPGP_TAG_SYM_ENC_INTEGRITY		18
81  /* Modification Detection Code Packet (Tag 19) */
82 
83 static const unsigned char pgp_header[5]= {0xa8, 0x03, 'P', 'G', 'P'};
84 
register_header_check_gpg(file_stat_t * file_stat)85 static void register_header_check_gpg(file_stat_t *file_stat)
86 {
87   static const unsigned char gpg_header_pkey_enc[1]= {0x85};
88   static const unsigned char gpg_header_symkey_enc[1]= {0x8c};
89   static const unsigned char gpg_header_seckey[1]= {0x95};
90 #if 1
91   static const unsigned char gpg_header_pkey[1]= {0x99};
92 #endif
93   register_header_check(0, gpg_header_seckey, sizeof(gpg_header_seckey), &header_check_gpg, file_stat);
94   register_header_check(0, gpg_header_symkey_enc, sizeof(gpg_header_symkey_enc), &header_check_gpg, file_stat);
95   register_header_check(0, gpg_header_pkey_enc, sizeof(gpg_header_pkey_enc), &header_check_gpg, file_stat);
96   register_header_check(0, pgp_header, sizeof(pgp_header), &header_check_gpg, file_stat);
97 #if 1
98   register_header_check(0, gpg_header_pkey, sizeof(gpg_header_pkey), &header_check_gpg, file_stat);
99 #endif
100 }
101 
openpgp_packet_tag(const unsigned char * buf)102 static unsigned int openpgp_packet_tag(const unsigned char *buf)
103 {
104   /* Bit 7 -- Always one */
105   if((buf[0]&0x80)==0)
106     return 0;	/* Invalid */
107   return ((buf[0]&0x40)==0?((buf[0]>>2)&0x0f):(buf[0]&0x3f));
108 }
109 
old_format_packet_length(const unsigned char * buf,unsigned int * length_type,int * indeterminate_length)110 static unsigned int old_format_packet_length(const unsigned char *buf, unsigned int *length_type, int *indeterminate_length)
111 {
112   /* Old format */
113   switch(buf[0]&0x3)
114   {
115     case 0:
116       *length_type=2;
117       return buf[1];
118     case 1:
119       *length_type=3;
120       return (buf[1] << 8) | buf[2];
121     case 2:
122       *length_type=5;
123       return (buf[1] << 24) |(buf[2] << 16) |  (buf[3] << 8) | buf[4];
124     default:
125       *length_type=1;
126       *indeterminate_length=1;
127       return 0;
128   }
129 }
130 
new_format_packet_length(const unsigned char * buf,unsigned int * length_type,int * partial_body_length)131 static unsigned int new_format_packet_length(const unsigned char *buf, unsigned int *length_type, int *partial_body_length)
132 {
133   *partial_body_length=0;
134   /* One-Octet Body Length */
135   if(buf[0]<=191)
136   {
137     *length_type=1;
138     return buf[0];
139   }
140   /* Two-Octet Body Length */
141   if(buf[0]<=223)
142   {
143     *length_type=2;
144     return ((buf[0] - 192) << 8) + buf[1] + 192;
145   }
146   /* Five-Octet Body Length */
147   if(buf[0]==255)
148   {
149     *length_type=5;
150     return (buf[1] << 24) | (buf[2] << 16) | (buf[3] << 8)  | buf[4];
151   }
152   /* Partial Body Lengths */
153   *length_type=1;
154   *partial_body_length=1;
155   return 1 << (buf[0]& 0x1F);
156 }
157 
is_valid_mpi(const uint16_t * size)158 static int is_valid_mpi(const uint16_t *size)
159 {
160   if(be16(*size) <= 16384)
161     return (be16(*size)+7)/8;
162   return -1;
163 }
164 
is_valid_pubkey_algo(const int algo)165 static  int is_valid_pubkey_algo(const int algo)
166 {
167   /*  1          - RSA (Encrypt or Sign)
168    *  2          - RSA Encrypt-Only
169    *  3          - RSA Sign-Only
170    *  16         - Elgamal (Encrypt-Only), see [ELGAMAL]
171    *  17         - DSA (Digital Signature Standard)
172    *  18         - Reserved for Elliptic Curve
173    *  19         - Reserved for ECDSA
174    *  20         - Elgamal (Encrypt or Sign)
175    *  21         - Reserved for Diffie-Hellman (X9.42, as defined for IETF-S/MIME)
176    *  100 to 110 - Private/Experimental algorithm
177    */
178   switch(algo)
179   {
180     case 1:
181     case 2:
182     case 3:
183     case 16:
184     case 17:
185     case 20:
186       return 1;
187     default:
188       return 0;
189   }
190 }
191 
is_valid_sym_algo(const int algo)192 static int is_valid_sym_algo(const int algo)
193 {
194   /*
195        0          - Plaintext or unencrypted data
196        1          - IDEA [IDEA]
197        2          - TripleDES (DES-EDE, [SCHNEIER] [HAC] -
198                     168 bit key derived from 192)
199        3          - CAST5 (128 bit key, as per [RFC2144])
200        4          - Blowfish (128 bit key, 16 rounds) [BLOWFISH]
201        5          - Reserved
202        6          - Reserved
203        7          - AES with 128-bit key [AES]
204        8          - AES with 192-bit key
205        9          - AES with 256-bit key
206        10         - Twofish with 256-bit key [TWOFISH]
207        100 to 110 - Private/Experimental algorithm
208        */
209   switch(algo)
210   {
211     case 1:
212     case 2:
213     case 3:
214     case 4:
215     case 7:
216     case 8:
217     case 9:
218     case 10:
219       return 1;
220     default:
221       return 0;
222   }
223 }
224 
is_valid_S2K(const unsigned int algo)225 static int is_valid_S2K(const unsigned int algo)
226 {
227   /*  ID          S2K Type
228    *  --          --------
229    *  0           Simple S2K
230    *  1           Salted S2K
231    *  2           Reserved value
232    *  3           Iterated and Salted S2K
233    *  100 to 110  Private/Experimental S2K
234    */
235   return (algo==0 || algo==1 || algo==3);
236 }
237 
file_check_gpg(file_recovery_t * file_recovery)238 static void file_check_gpg(file_recovery_t *file_recovery)
239 {
240   unsigned int tag=0;
241   unsigned int nbr=0;
242   int partial_body_length=0;
243   int stop=0;
244   off_t offset=0;
245   unsigned char buffer[32];
246   const uint64_t org_file_size=file_recovery->file_size;
247   file_recovery->file_size=0;
248   while(stop==0)
249   {
250     unsigned int i=0;
251     unsigned int length_type=0;
252     unsigned int length;
253     const int old_partial_body_length=partial_body_length;
254     if(my_fseek(file_recovery->handle, offset, SEEK_SET) < 0 ||
255 	fread(&buffer, sizeof(buffer), 1, file_recovery->handle) != 1)
256       return;
257 
258     if(partial_body_length==0)
259     {
260       if((buffer[i]&0x80)==0)
261 	break;	/* Invalid */
262       tag=openpgp_packet_tag(&buffer[i]);
263       if((buffer[i]&0x40)==0)
264       {
265 	length=old_format_packet_length(&buffer[i], &length_type, &stop);
266       }
267       else
268       {
269 	length=new_format_packet_length(&buffer[i+1], &length_type, &partial_body_length);
270 	length_type++;
271       }
272     }
273     else
274     {
275       length=new_format_packet_length(&buffer[i], &length_type, &partial_body_length);
276     }
277 #ifdef DEBUG_GPG
278     log_info("GPG 0x%04x: %02u tag=%2u, size=%u + %u)\n",
279 	i, nbr, tag, length_type, length);
280 #endif
281 #if 0
282     if(tag==0 || tag==15 || (tag>19 && tag!=61))	/* Reserved or unused */
283       return;
284 #endif
285     if(length_type==0)
286       break;	/* Don't know how to find the size */
287     i+=length_type;
288     offset+=length_type;
289     if(old_partial_body_length==0)
290     {
291       if(tag==OPENPGP_TAG_PUBKEY_ENC_SESSION_KEY)
292       {
293 	const uint16_t *mpi=(const uint16_t *)&buffer[i+1+8+1];
294 	const int len=is_valid_mpi(mpi);
295 	/* uint8_t  version	must be 3
296 	 * uint64_t pub_key_id
297 	 * uint8_t  pub_key_algo
298 	 *          encrypted_session_key	*/
299 	if(buffer[i]==3 && is_valid_pubkey_algo(buffer[i+1+8]) &&
300 	    len>0)
301 	{
302 #ifdef DEBUG_GPG
303 	  log_info("GPG :pubkey enc packet: version %u, algo %u, keyid %02X%02X%02X%02X%02X%02X%02X%02X\n",
304 	      buffer[i], buffer[i+1+8],
305 	      buffer[i+1], buffer[i+2], buffer[i+3], buffer[i+4],
306 	      buffer[i+5], buffer[i+6], buffer[i+7], buffer[i+8]);
307 	  log_info(" data: [ %u bits]\n", be16(*mpi));
308 #endif
309 	  if((unsigned)(1+8+1+2+len) > length)
310 	    return ;
311 	  if(buffer[i+1+8]==16 || buffer[i+1+8]==20)
312 	  {
313 	    int len2;
314 	    unsigned char tmp[2];
315 	    if(my_fseek(file_recovery->handle, offset+1+8+1+2+len, SEEK_SET) < 0 ||
316 		fread(&tmp, sizeof(tmp), 1, file_recovery->handle) != 1)
317 	      return;
318 	    mpi=(const uint16_t *)&tmp[0];
319 	    len2=is_valid_mpi(mpi);
320 #ifdef DEBUG_GPG
321 	    log_info(" data: [ %u bits]\n", be16(*mpi));
322 #endif
323 	    if(len2 <= 0)
324 	      return ;
325 	    if((unsigned)(1+8+1+2+len+2+len2) > length)
326 	      return ;
327 	  }
328 	}
329 	else
330 	  return;
331       }
332       else if(tag==OPENPGP_TAG_SIGNATURE)
333       {
334 	/* v3 - length=5 */
335 	if(buffer[i]==3 && buffer[i+1]==5 && is_valid_pubkey_algo(buffer[i+1+1+5+8]))
336 	{
337 #ifdef DEBUG_GPG
338 	  log_info(":signature packet: algo %u\n", buffer[i+1+1+5+8]);
339 	  log_info(":signature packet: sig_class 0x%02x\n", buffer[i+1+1]);
340 #endif
341 	}
342 	/* v4 */
343 	else if(buffer[i]==4 && is_valid_pubkey_algo(buffer[i+2]))
344 	{
345 #ifdef DEBUG_GPG
346 	  log_info(":signature packet: algo %u\n", buffer[i+2]);
347 #endif
348 	}
349 	else
350 	  return;
351       }
352       else if(tag==OPENPGP_TAG_SYMKEY_ENC_SESSION_KEY)
353       {
354 	/* v4 */
355 	if(buffer[i]==4 && is_valid_sym_algo(buffer[i+1]) && is_valid_S2K(buffer[i+2]))
356 	{
357 	}
358 	else
359 	  return;
360       }
361       else if(tag==OPENPGP_TAG_ONE_PASS_SIG)
362       {
363 	if(buffer[i]==3 && is_valid_sym_algo(buffer[i+1]))
364 	{
365 	}
366 	else
367 	  return;
368       }
369       else if(tag==OPENPGP_TAG_SYM_ENC_DATA)
370       {
371       }
372       else if(tag==OPENPGP_TAG_MARKER)
373       {
374 	/* Must be at the beginning of the packet */
375 	if(nbr!=0)
376 	  return;
377       }
378       else if(tag==OPENPGP_TAG_SYM_ENC_INTEGRITY)
379       {
380 #ifdef DEBUG_GPG
381 	log_info("GPG :encrypted data packet:\n");
382 #endif
383 	/* Version must be 1 */
384 	if(buffer[i]!=1)
385 	  return;
386       }
387       else if(tag==OPENPGP_TAG_PUB_KEY ||
388 	  tag==OPENPGP_TAG_PUB_SUBKEY ||
389 	  tag==OPENPGP_TAG_SEC_KEY||
390 	  tag==OPENPGP_TAG_SEC_SUBKEY)
391       {
392 	if((buffer[i]==2 || buffer[i]==3) && is_valid_pubkey_algo(buffer[i+1+4+2]))
393 	{ /* version 2 or 3 */
394 	}
395 	else if(buffer[i]==4 && is_valid_pubkey_algo(buffer[i+1+4]))
396 	{ /* version 4 */
397 	}
398 	else
399 	  return;
400       }
401     }
402     if(partial_body_length==0)
403       nbr++;
404     offset+=length;
405   }
406   if(nbr<2)
407     return;
408   file_recovery->file_size=(stop==0?org_file_size:(uint64_t)offset);
409 }
410 
header_check_gpg(const unsigned char * buffer,const unsigned int buffer_size,const unsigned int safe_header_only,const file_recovery_t * file_recovery,file_recovery_t * file_recovery_new)411 static int header_check_gpg(const unsigned char *buffer, const unsigned int buffer_size, const unsigned int safe_header_only, const file_recovery_t *file_recovery, file_recovery_t *file_recovery_new)
412 {
413   uint64_t i=0;
414   unsigned int packet_tag[16];
415   unsigned int nbr=0;
416   int partial_body_length=0;
417   int stop=0;
418   memset(packet_tag, 0, sizeof(packet_tag));
419   while(nbr<16 && i < buffer_size - 20 && stop==0)
420   {
421     unsigned int length_type=0;
422     unsigned int tag;
423     unsigned int length;
424     const int old_partial_body_length=partial_body_length;
425     if(partial_body_length==0)
426     {
427       if((buffer[i]&0x80)==0)
428 	break;	/* Invalid */
429       packet_tag[nbr]=openpgp_packet_tag(&buffer[i]);
430       if((buffer[i]&0x40)==0)
431       {
432 	length=old_format_packet_length(&buffer[i], &length_type, &stop);
433       }
434       else
435       {
436 	length=new_format_packet_length(&buffer[i+1], &length_type, &partial_body_length);
437 	length_type++;
438       }
439     }
440     else
441     {
442       length=new_format_packet_length(&buffer[i], &length_type, &partial_body_length);
443     }
444     tag=packet_tag[nbr];
445 #ifdef DEBUG_GPG
446     log_info("GPG 0x%04x: %02u tag=%2u, size=%u + %u)\n",
447 	i, nbr, tag, length_type, length);
448 #endif
449 #if 0
450     if(tag==0 || tag==15 || (tag>19 && tag!=61))	/* Reserved or unused */
451       return 0;
452 #endif
453     if(length_type==0)
454       break;	/* Don't know how to find the size */
455     i+=length_type;
456     if(old_partial_body_length==0)
457     {
458       if(tag==OPENPGP_TAG_PUBKEY_ENC_SESSION_KEY)
459       {
460 	const uint16_t *mpi=(const uint16_t *)&buffer[i+1+8+1];
461 	const int len=is_valid_mpi(mpi);
462 	/* uint8_t  version	must be 3
463 	 * uint64_t pub_key_id
464 	 * uint8_t  pub_key_algo
465 	 *          encrypted_session_key	*/
466 	if(buffer[i]==3 && is_valid_pubkey_algo(buffer[i+1+8]) &&
467 	    len>0)
468 	{
469 #ifdef DEBUG_GPG
470 	  log_info("GPG :pubkey enc packet: version %u, algo %u, keyid %02X%02X%02X%02X%02X%02X%02X%02X\n",
471 	      buffer[i], buffer[i+1+8],
472 	      buffer[i+1], buffer[i+2], buffer[i+3], buffer[i+4],
473 	      buffer[i+5], buffer[i+6], buffer[i+7], buffer[i+8]);
474 	  log_info(" data: [ %u bits]\n", be16(*mpi));
475 #endif
476 	  if((unsigned)(1+8+1+2+len) > length)
477 	    return 0;
478 	  if((buffer[i+1+8]==16 || buffer[i+1+8]==20) &&
479 	      i+1+8+1+2+len+2<buffer_size)
480 	  {
481 	    int len2;
482 	    mpi=(const uint16_t *)&buffer[i+1+8+1+2+len];
483 	    len2=is_valid_mpi(mpi);
484 #ifdef DEBUG_GPG
485 	    log_info(" data: [ %u bits]\n", be16(*mpi));
486 #endif
487 	    if(len2 <= 0)
488 	      return 0;
489 	    if((unsigned)(1+8+1+2+len+2+len2) > length)
490 	      return 0;
491 	  }
492 	}
493 	else
494 	  return 0;
495       }
496       else if(tag==OPENPGP_TAG_SIGNATURE)
497       {
498 	/* v3 - length=5 */
499 	if(buffer[i]==3 && buffer[i+1]==5 && is_valid_pubkey_algo(buffer[i+1+1+5+8]))
500 	{
501 #ifdef DEBUG_GPG
502 	  log_info(":signature packet: algo %u\n", buffer[i+1+1+5+8]);
503 	  log_info(":signature packet: sig_class 0x%02x\n", buffer[i+1+1]);
504 #endif
505 	}
506 	/* v4 */
507 	else if(buffer[i]==4 && is_valid_pubkey_algo(buffer[i+2]))
508 	{
509 #ifdef DEBUG_GPG
510 	  log_info(":signature packet: algo %u\n", buffer[i+2]);
511 #endif
512 	}
513 	else
514 	  return 0;
515       }
516       else if(tag==OPENPGP_TAG_SYMKEY_ENC_SESSION_KEY)
517       {
518 	/* v4 */
519 	if(buffer[i]==4 && is_valid_sym_algo(buffer[i+1]) && is_valid_S2K(buffer[i+2]))
520 	{
521 	}
522 	else
523 	  return 0;
524       }
525       else if(tag==OPENPGP_TAG_ONE_PASS_SIG)
526       {
527 	if(buffer[i]==3 && is_valid_sym_algo(buffer[i+1]))
528 	{
529 	}
530 	else
531 	  return 0;
532       }
533       else if(tag==OPENPGP_TAG_SYM_ENC_DATA)
534       {
535 	unsigned int j;
536 	int ok=0;
537 	/* The symmetric cipher used may be specified in a Public-Key or
538 	 * Symmetric-Key Encrypted Session Key packet that precedes the
539 	 * Symmetrically Encrypted Data packet.
540 	 * PhotoRec assumes it must */
541 	for(j=0; j<nbr; j++)
542 	{
543 	  if(packet_tag[j]==OPENPGP_TAG_PUBKEY_ENC_SESSION_KEY ||
544 	      packet_tag[j]==OPENPGP_TAG_SYMKEY_ENC_SESSION_KEY)
545 	    ok=1;
546 	}
547 	if(ok==0)
548 	  return 0;
549       }
550       else if(tag==OPENPGP_TAG_MARKER)
551       {
552 	/* Must be at the beginning of the packet */
553 	if(nbr!=0)
554 	  return 0;
555       }
556       else if(tag==OPENPGP_TAG_SYM_ENC_INTEGRITY)
557       {
558 	unsigned int j;
559 	int ok=0;
560 #ifdef DEBUG_GPG
561 	log_info("GPG :encrypted data packet:\n");
562 #endif
563 	/* Version must be 1 */
564 	if(buffer[i]!=1)
565 	  return 0;
566 	/* The symmetric cipher used MUST be specified in a Public-Key or
567 	 * Symmetric-Key Encrypted Session Key packet that precedes the
568 	 * Symmetrically Encrypted Data packet. */
569 	for(j=0; j<nbr; j++)
570 	{
571 	  if(packet_tag[j]==OPENPGP_TAG_PUBKEY_ENC_SESSION_KEY ||
572 	      packet_tag[j]==OPENPGP_TAG_SYMKEY_ENC_SESSION_KEY)
573 	    ok=1;
574 	}
575 	if(ok==0)
576 	  return 0;
577       }
578       else if(tag==OPENPGP_TAG_PUB_KEY ||
579 	  tag==OPENPGP_TAG_PUB_SUBKEY ||
580 	  tag==OPENPGP_TAG_SEC_KEY||
581 	  tag==OPENPGP_TAG_SEC_SUBKEY)
582       {
583 	if((buffer[i]==2 || buffer[i]==3) && is_valid_pubkey_algo(buffer[i+1+4+2]))
584 	{ /* version 2 or 3 */
585 	}
586 	else if(buffer[i]==4 && is_valid_pubkey_algo(buffer[i+1+4]))
587 	{ /* version 4 */
588 	}
589 	else
590 	  return 0;
591       }
592     }
593     if(partial_body_length==0)
594       nbr++;
595     i+=length;
596   }
597   if(nbr<2)
598     return 0;
599   if(memcmp(buffer, pgp_header, sizeof(pgp_header))==0)
600   {
601     reset_file_recovery(file_recovery_new);
602     file_recovery_new->file_check=&file_check_gpg;
603     file_recovery_new->extension="pgp";
604     return 1;
605   }
606   if( /* encrypted_data.gpg */
607       ((packet_tag[0]==OPENPGP_TAG_PUBKEY_ENC_SESSION_KEY ||
608 	packet_tag[0]==OPENPGP_TAG_SYMKEY_ENC_SESSION_KEY) &&
609        (packet_tag[1]==OPENPGP_TAG_SYM_ENC_DATA ||
610 	packet_tag[1]==OPENPGP_TAG_SYM_ENC_INTEGRITY)) ||
611        /* pubring.gpg */
612       (packet_tag[0]==OPENPGP_TAG_PUB_KEY &&
613        packet_tag[1]==OPENPGP_TAG_USER_ID &&
614        packet_tag[2]==OPENPGP_TAG_SIGNATURE &&
615        packet_tag[3]==OPENPGP_TAG_TRUST) ||
616       (packet_tag[0]==OPENPGP_TAG_PUB_KEY &&
617        packet_tag[1]==OPENPGP_TAG_USER_ID &&
618        packet_tag[2]==OPENPGP_TAG_SIGNATURE &&
619        packet_tag[3]==OPENPGP_TAG_PUB_SUBKEY) ||
620        /* secring.gpg */
621       (packet_tag[0]==OPENPGP_TAG_SEC_KEY &&
622        packet_tag[1]==OPENPGP_TAG_USER_ID &&
623        packet_tag[2]==OPENPGP_TAG_SIGNATURE &&
624        packet_tag[3]==OPENPGP_TAG_TRUST) ||
625       (packet_tag[0]==OPENPGP_TAG_SEC_KEY &&
626        packet_tag[1]==61 &&
627        packet_tag[2]==61 &&
628        packet_tag[3]==61)
629     )
630   {
631     reset_file_recovery(file_recovery_new);
632     file_recovery_new->file_check=&file_check_gpg;
633     file_recovery_new->extension=file_hint_gpg.extension;
634     return 1;
635   }
636 #ifdef DEBUG_GPG
637   log_info("tag don't match: nbr=%u - ", nbr);
638   for(i=0; i<nbr; i++)
639     log_info(" %u", packet_tag[i]);
640   log_info("\n");
641 #endif
642   return 0;
643 }
644