1
0
mirror of git://git.gnupg.org/gnupg.git synced 2024-12-22 10:19:57 +01:00

gpg: Allow --dearmor to decode all kinds of armor files.

* g10/filter.h (armor_filter_context_t): New fields dearmor_mode and
dearmor_state.
* g10/dearmor.c (dearmor_file): Set dearmor_mode.
* g10/armor.c (is_armor_header): Magic to switch to generic dearmor
mode.
(parse_header_line): Treat non OpenPGP armor in a special way.
(check_input): Ditto.
(radix64_read): Detect non OpenPGP armor END lines.
This commit is contained in:
Werner Koch 2022-01-28 12:09:34 +01:00
parent f2d1187fcd
commit 34ea19aff9
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B
4 changed files with 35 additions and 8 deletions

View File

@ -630,6 +630,7 @@ with ant release.
@opindex dearmor @opindex dearmor
Pack or unpack an arbitrary input into/from an OpenPGP ASCII armor. Pack or unpack an arbitrary input into/from an OpenPGP ASCII armor.
This is a GnuPG extension to OpenPGP and in general not very useful. This is a GnuPG extension to OpenPGP and in general not very useful.
The @option{--dearmor} command can also be used to dearmor PEM armors.
@item --unwrap @item --unwrap
@opindex unwrap @opindex unwrap

View File

@ -381,9 +381,9 @@ is_armor_tag(const char *line)
} }
/**************** /****************
* Check whether this is a armor line. * Check whether this is a armor line. Returns: -1 if it is not a
* returns: -1 if it is not a armor header or the index number of the * armor header, 42 if it is a generic header, or the index number of
* armor header. * the armor header.
*/ */
static int static int
is_armor_header( byte *line, unsigned len ) is_armor_header( byte *line, unsigned len )
@ -430,8 +430,12 @@ is_armor_header( byte *line, unsigned len )
if( !strcmp(s, p) ) if( !strcmp(s, p) )
break; break;
*save_p = save_c; *save_p = save_c;
if( !s ) if (!s)
{
if (!strncmp (p, "BEGIN ", 6))
return 42;
return -1; /* unknown armor line */ return -1; /* unknown armor line */
}
if( opt.verbose > 1 ) if( opt.verbose > 1 )
log_info(_("armor: %s\n"), head_strings[i]); log_info(_("armor: %s\n"), head_strings[i]);
@ -470,6 +474,8 @@ parse_header_line( armor_filter_context_t *afx, byte *line, unsigned int len )
*/ */
p = strchr( line, ':'); p = strchr( line, ':');
if (!p && afx->dearmor_state)
return 0; /* Special treatment in --dearmor mode. */
if( !p || (RFC2440 && p[1]!=' ') if( !p || (RFC2440 && p[1]!=' ')
|| (!RFC2440 && p[1]!=' ' && p[1]!='\n' && p[1]!='\r')) || (!RFC2440 && p[1]!=' ' && p[1]!='\n' && p[1]!='\r'))
{ {
@ -489,7 +495,9 @@ parse_header_line( armor_filter_context_t *afx, byte *line, unsigned int len )
log_printf ("\n"); log_printf ("\n");
} }
if( afx->in_cleartext ) if (afx->dearmor_mode)
;
else if (afx->in_cleartext)
{ {
if( (hashes=parse_hash_header( line )) ) if( (hashes=parse_hash_header( line )) )
afx->hashes |= hashes; afx->hashes |= hashes;
@ -559,17 +567,25 @@ check_input( armor_filter_context_t *afx, IOBUF a )
/* find the armor header */ /* find the armor header */
while(len) { while(len) {
i = is_armor_header( line, len ); i = is_armor_header( line, len );
if( i >= 0 && !(afx->only_keyblocks && i != 1 && i != 5 && i != 6 )) { if ( i == 42 ) {
if (afx->dearmor_mode) {
afx->dearmor_state = 1;
break;
}
}
else if (i >= 0
&& !(afx->only_keyblocks && i != 1 && i != 5 && i != 6 )) {
hdr_line = i; hdr_line = i;
if( hdr_line == BEGIN_SIGNED_MSG_IDX ) { if( hdr_line == BEGIN_SIGNED_MSG_IDX ) {
if( afx->in_cleartext ) { if( afx->in_cleartext ) {
log_error(_("nested clear text signatures\n")); log_error(_("nested clear text signatures\n"));
rc = gpg_error (GPG_ERR_INV_ARMOR); rc = gpg_error (GPG_ERR_INV_ARMOR);
} }
afx->in_cleartext = 1; afx->in_cleartext = 1;
} }
break; break;
} }
/* read the next line (skip all truncated lines) */ /* read the next line (skip all truncated lines) */
do { do {
maxlen = MAX_LINELEN; maxlen = MAX_LINELEN;
@ -692,6 +708,8 @@ fake_packet( armor_filter_context_t *afx, IOBUF a,
/* Five dashes in a row mean it's probably armor /* Five dashes in a row mean it's probably armor
header. */ header. */
int type = is_armor_header( p, n ); int type = is_armor_header( p, n );
if (type == 42)
type = -1; /* Only OpenPGP armors are expected. */
if( afx->not_dash_escaped && type != BEGIN_SIGNATURE ) if( afx->not_dash_escaped && type != BEGIN_SIGNATURE )
; /* this is okay */ ; /* this is okay */
else else
@ -998,6 +1016,11 @@ radix64_read( armor_filter_context_t *afx, IOBUF a, size_t *retn,
checkcrc++; checkcrc++;
break; break;
} }
else if (afx->dearmor_state && c == '-'
&& afx->buffer_pos + 8 < afx->buffer_len
&& !strncmp (afx->buffer, "-----END ", 8)) {
break; /* End in --dearmor mode. */
}
else { else {
log_error(_("invalid radix64 character %02X skipped\n"), c); log_error(_("invalid radix64 character %02X skipped\n"), c);
continue; continue;

View File

@ -45,6 +45,7 @@ dearmor_file( const char *fname )
int c; int c;
afx = new_armor_context (); afx = new_armor_context ();
afx->dearmor_mode = 1;
/* prepare iobufs */ /* prepare iobufs */
inp = iobuf_open(fname); inp = iobuf_open(fname);

View File

@ -35,6 +35,7 @@ typedef struct {
/* these fields may be initialized */ /* these fields may be initialized */
int what; /* what kind of armor headers to write */ int what; /* what kind of armor headers to write */
int only_keyblocks; /* skip all headers but ".... key block" */ int only_keyblocks; /* skip all headers but ".... key block" */
int dearmor_mode; /* dearmor all kind of stuff. */
const char *hdrlines; /* write these headerlines */ const char *hdrlines; /* write these headerlines */
/* these fields must be initialized to zero */ /* these fields must be initialized to zero */
@ -49,6 +50,7 @@ typedef struct {
int faked; /* we are faking a literal data packet */ int faked; /* we are faking a literal data packet */
int truncated; /* number of truncated lines */ int truncated; /* number of truncated lines */
int qp_detected; int qp_detected;
int dearmor_state; /* helper for dearmor_mode. */
byte eol[3]; /* The end of line characters as a byte eol[3]; /* The end of line characters as a
zero-terminated string. Defaults zero-terminated string. Defaults
(eol[0]=='\0') to whatever the local (eol[0]=='\0') to whatever the local