diff options
author | Werner Koch <[email protected]> | 2016-07-13 13:11:46 +0000 |
---|---|---|
committer | Werner Koch <[email protected]> | 2016-07-13 13:11:46 +0000 |
commit | 4ef62278e3c9406360dc50288f422291497e218f (patch) | |
tree | fff3a49be5c2659ab87195e5b0a4f88e51a49205 /common/b64dec.c | |
parent | Merge branch 'master' into STABLE-BRANCH-2-2 (diff) | |
parent | gpg: New option --mimemode. (diff) | |
download | gnupg-4ef62278e3c9406360dc50288f422291497e218f.tar.gz gnupg-4ef62278e3c9406360dc50288f422291497e218f.zip |
Merge branch 'master' into STABLE-BRANCH-2-2
--
Diffstat (limited to 'common/b64dec.c')
-rw-r--r-- | common/b64dec.c | 79 |
1 files changed, 47 insertions, 32 deletions
diff --git a/common/b64dec.c b/common/b64dec.c index 3e02e4afa..c84c35ada 100644 --- a/common/b64dec.c +++ b/common/b64dec.c @@ -1,29 +1,20 @@ /* b64dec.c - Simple Base64 decoder. * Copyright (C) 2008, 2011 Free Software Foundation, Inc. + * Copyright (C) 2008, 2011, 2016 g10 Code GmbH * * This file is part of GnuPG. * * This file is free software; you can redistribute it and/or modify - * it under the terms of either - * - * - the GNU Lesser General Public License as published by the Free - * Software Foundation; either version 3 of the License, or (at - * your option) any later version. - * - * or - * - * - the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at - * your option) any later version. - * - * or both in parallel, as here. + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. * * This file is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License + * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, see <http://www.gnu.org/licenses/>. */ @@ -61,7 +52,7 @@ static unsigned char const asctobin[128] = enum decoder_states { - s_init, s_idle, s_lfseen, s_begin, + s_init, s_idle, s_lfseen, s_beginseen, s_waitheader, s_waitblank, s_begin, s_b64_0, s_b64_1, s_b64_2, s_b64_3, s_waitendtitle, s_waitend }; @@ -71,26 +62,18 @@ enum decoder_states /* Initialize the context for the base64 decoder. If TITLE is NULL a plain base64 decoding is done. If it is the empty string the decoder will skip everything until a "-----BEGIN " line has been - seen, decoding ends at a "----END " line. - - Not yet implemented: If TITLE is either "PGP" or begins with "PGP " - the PGP armor lines are skipped as well. */ + seen, decoding ends at a "----END " line. */ gpg_error_t b64dec_start (struct b64state *state, const char *title) { memset (state, 0, sizeof *state); if (title) { - if (!strncmp (title, "PGP", 3) && (!title[3] || title[3] == ' ')) - state->lasterr = gpg_error (GPG_ERR_NOT_IMPLEMENTED); + state->title = xtrystrdup (title); + if (!state->title) + state->lasterr = gpg_error_from_syserror (); else - { - state->title = xtrystrdup (title); - if (!state->title) - state->lasterr = gpg_error_from_syserror (); - else - state->idx = s_init; - } + state->idx = s_init; } else state->idx = s_b64_0; @@ -123,6 +106,7 @@ b64dec_proc (struct b64state *state, void *buffer, size_t length, for (s=d=buffer; length && !state->stop_seen; length--, s++) { + again: switch (ds) { case s_idle: @@ -136,12 +120,42 @@ b64dec_proc (struct b64state *state, void *buffer, size_t length, ds = s_lfseen; case s_lfseen: if (*s != "-----BEGIN "[pos]) - ds = s_idle; + { + ds = s_idle; + goto again; + } else if (pos == 10) - ds = s_begin; + { + pos = 0; + ds = s_beginseen; + } + else + pos++; + break; + case s_beginseen: + if (*s != "PGP "[pos]) + ds = s_begin; /* Not a PGP armor. */ + else if (pos == 3) + ds = s_waitheader; else pos++; break; + case s_waitheader: + if (*s == '\n') + ds = s_waitblank; + break; + case s_waitblank: + if (*s == '\n') + ds = s_b64_0; /* blank line found. */ + else if (*s == ' ' || *s == '\r' || *s == '\t') + ; /* Ignore spaces. */ + else + { + /* Armor header line. Note that we don't care that our + * FSM accepts a header prefixed with spaces. */ + ds = s_waitheader; /* Wait for next header. */ + } + break; case s_begin: if (*s == '\n') ds = s_b64_0; @@ -229,10 +243,11 @@ b64dec_proc (struct b64state *state, void *buffer, size_t length, gpg_error_t b64dec_finish (struct b64state *state) { + xfree (state->title); + state->title = NULL; + if (state->lasterr) return state->lasterr; - xfree (state->title); - state->title = NULL; return state->invalid_encoding? gpg_error(GPG_ERR_BAD_DATA): 0; } |