summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2004-02-10 20:27:54 +0100
committerWerner Koch <wk@gnupg.org>2004-02-10 20:27:54 +0100
commitf0d63ef75d2f03d41260e2c6a9f277cbcd71987a (patch)
tree3f18ce280ff38cf44e78741850cfec9848506bdf
parent* minip12.c (parse_bag_encrypted_data): Finished implementation. (diff)
downloadgnupg2-f0d63ef75d2f03d41260e2c6a9f277cbcd71987a.tar.xz
gnupg2-f0d63ef75d2f03d41260e2c6a9f277cbcd71987a.zip
New. Based on code from ../sm/base64.c.
-rw-r--r--common/ChangeLog4
-rw-r--r--common/Makefile.am1
-rw-r--r--common/b64enc.c211
-rw-r--r--common/util.h20
4 files changed, 234 insertions, 2 deletions
diff --git a/common/ChangeLog b/common/ChangeLog
index 1266a88c5..6355f350a 100644
--- a/common/ChangeLog
+++ b/common/ChangeLog
@@ -1,3 +1,7 @@
+2004-02-10 Werner Koch <wk@gnupg.org>
+
+ * b64enc.c: New. Based on code from ../sm/base64.c.
+
2004-01-30 Marcus Brinkmann <marcus@g10code.de>
* Makefile.am (libcommon_a_SOURCES): Add xasprintf.c.
diff --git a/common/Makefile.am b/common/Makefile.am
index 640051be4..393e48435 100644
--- a/common/Makefile.am
+++ b/common/Makefile.am
@@ -34,6 +34,7 @@ libcommon_a_SOURCES = \
sysutils.c sysutils.h \
gettime.c \
yesno.c \
+ b64enc.c \
miscellaneous.c \
xasprintf.c \
membuf.c membuf.h \
diff --git a/common/b64enc.c b/common/b64enc.c
new file mode 100644
index 000000000..edcf6e3ad
--- /dev/null
+++ b/common/b64enc.c
@@ -0,0 +1,211 @@
+/* b64enc.c - Simple Base64 encoder.
+ * Copyright (C) 2001, 2003, 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of GnuPG.
+ *
+ * GnuPG is free software; you can redistribute it and/or modify
+ * it under the terms of 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.
+ *
+ * GnuPG 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
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include <config.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <assert.h>
+
+#include "i18n.h"
+#include "util.h"
+
+#define B64ENC_DID_HEADER 1
+#define B64ENC_DID_TRAILER 2
+#define B64ENC_NO_LINEFEEDS 16
+
+
+/* The base-64 character list */
+static unsigned char bintoasc[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "abcdefghijklmnopqrstuvwxyz"
+ "0123456789+/";
+
+/* Prepare for base-64 writing to the stream FP. If TITLE is not NULL
+ and not an empty string, this string will be used as the title for
+ the armor lines, with TITLE being an empty string, we don't write
+ the header lines and furthermore even don't write any linefeeds.
+ With TITLE beeing NULL, we merely don't write header but make sure
+ that lines are not too long. Note, that we don't write any output
+ unless at least one byte get written using b64enc_write. */
+gpg_error_t
+b64enc_start (struct b64state *state, FILE *fp, const char *title)
+{
+ memset (state, 0, sizeof *state);
+ state->fp = fp;
+ if (title && !*title)
+ state->flags |= B64ENC_NO_LINEFEEDS;
+ else if (title)
+ {
+ state->title = xtrystrdup (title);
+ if (!state->title)
+ return gpg_error_from_errno (errno);
+ }
+ return 0;
+}
+
+
+/* Write NBYTES from BUFFER to the Base 64 stream identified by
+ STATE. With BUFFER and NBYTES being 0, merely do a fflush on the
+ stream. */
+gpg_error_t
+b64enc_write (struct b64state *state, const void *buffer, size_t nbytes)
+{
+ unsigned char radbuf[4];
+ int idx, quad_count;
+ const unsigned char *p;
+ FILE *fp = state->fp;
+
+
+ if (!nbytes)
+ {
+ if (buffer && fflush (fp))
+ goto write_error;
+ return 0;
+ }
+
+ if (!(state->flags & B64ENC_DID_HEADER))
+ {
+ if (state->title)
+ {
+ if ( fputs ("-----BEGIN ", fp) == EOF
+ || fputs (state->title, fp) == EOF
+ || fputs ("-----\n", fp) == EOF)
+ goto write_error;
+ }
+ state->flags |= B64ENC_DID_HEADER;
+ }
+
+ idx = state->idx;
+ quad_count = state->quad_count;
+ assert (idx < 4);
+ memcpy (radbuf, state->radbuf, idx);
+
+ for (p=buffer; nbytes; p++, nbytes--)
+ {
+ radbuf[idx++] = *p;
+ if (idx > 2)
+ {
+ char tmp[4];
+
+ tmp[0] = bintoasc[(*radbuf >> 2) & 077];
+ tmp[1] = bintoasc[(((*radbuf<<4)&060)|((radbuf[1] >> 4)&017))&077];
+ tmp[2] = bintoasc[(((radbuf[1]<<2)&074)|((radbuf[2]>>6)&03))&077];
+ tmp[3] = bintoasc[radbuf[2]&077];
+ for (idx=0; idx < 4; idx++)
+ putc (tmp[idx], fp);
+ idx = 0;
+ if (ferror (fp))
+ goto write_error;
+ if (++quad_count >= (64/4))
+ {
+ quad_count = 0;
+ if (!(state->flags & B64ENC_NO_LINEFEEDS)
+ && fputs ("\n", fp) == EOF)
+ goto write_error;
+ }
+ }
+ }
+ memcpy (state->radbuf, radbuf, idx);
+ state->idx = idx;
+ state->quad_count = quad_count;
+ return 0;
+
+ write_error:
+ return gpg_error_from_errno (errno);
+}
+
+gpg_error_t
+b64enc_finish (struct b64state *state)
+{
+ gpg_error_t err = 0;
+ unsigned char radbuf[4];
+ int idx, quad_count;
+ FILE *fp;
+
+ if (!(state->flags & B64ENC_DID_HEADER))
+ goto cleanup;
+
+ /* Flush the base64 encoding */
+ fp = state->fp;
+ idx = state->idx;
+ quad_count = state->quad_count;
+ assert (idx < 4);
+ memcpy (radbuf, state->radbuf, idx);
+
+ if (idx)
+ {
+ char tmp[4];
+
+ tmp[0] = bintoasc[(*radbuf>>2)&077];
+ if (idx == 1)
+ {
+ tmp[1] = bintoasc[((*radbuf << 4) & 060) & 077];
+ tmp[2] = '=';
+ tmp[3] = '=';
+ }
+ else
+ {
+ tmp[1] = bintoasc[(((*radbuf<<4)&060)|((radbuf[1]>>4)&017))&077];
+ tmp[2] = bintoasc[((radbuf[1] << 2) & 074) & 077];
+ tmp[3] = '=';
+ }
+ for (idx=0; idx < 4; idx++)
+ putc (tmp[idx], fp);
+ idx = 0;
+ if (ferror (fp))
+ goto write_error;
+
+ if (++quad_count >= (64/4))
+ {
+ quad_count = 0;
+ if (!(state->flags & B64ENC_NO_LINEFEEDS)
+ && fputs ("\n", fp) == EOF)
+ goto write_error;
+ }
+ }
+
+ /* Finish the last line and write the trailer. */
+ if (quad_count
+ && !(state->flags & B64ENC_NO_LINEFEEDS)
+ && fputs ("\n", fp) == EOF)
+ goto write_error;
+
+ if (state->title)
+ {
+ if ( fputs ("-----END ", fp) == EOF
+ || fputs (state->title, fp) == EOF
+ || fputs ("-----\n", fp) == EOF)
+ goto write_error;
+ }
+
+ goto cleanup;
+
+ write_error:
+ err = gpg_error_from_errno (errno);
+
+ cleanup:
+ if (state->title)
+ {
+ xfree (state->title);
+ state->title = NULL;
+ }
+ state->fp = NULL;
+ return err;
+}
+
diff --git a/common/util.h b/common/util.h
index 7e134e846..ca7266627 100644
--- a/common/util.h
+++ b/common/util.h
@@ -1,5 +1,5 @@
-/* util.h - Utility functions for Gnupg
- * Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
+/* util.h - Utility functions for GnuPG
+ * Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@@ -98,6 +98,22 @@ int answer_is_yes_no_default (const char *s, int def_answer);
int answer_is_yes_no_quit (const char *s);
+/*-- b64enc.c --*/
+struct b64state
+{
+ unsigned int flags;
+ int idx;
+ int quad_count;
+ FILE *fp;
+ char *title;
+ unsigned char radbuf[4];
+};
+gpg_error_t b64enc_start (struct b64state *state, FILE *fp, const char *title);
+gpg_error_t b64enc_write (struct b64state *state,
+ const void *buffer, size_t nbytes);
+gpg_error_t b64enc_finish (struct b64state *state);
+
+
/*-- miscellaneous.c --*/
/* Same as asprintf but return an allocated buffer suitable to be