aboutsummaryrefslogtreecommitdiffstats
path: root/g10/encr-data.c
diff options
context:
space:
mode:
Diffstat (limited to 'g10/encr-data.c')
-rw-r--r--g10/encr-data.c122
1 files changed, 122 insertions, 0 deletions
diff --git a/g10/encr-data.c b/g10/encr-data.c
new file mode 100644
index 000000000..5c047e90d
--- /dev/null
+++ b/g10/encr-data.c
@@ -0,0 +1,122 @@
+/* encr-data.c - process an encrypted data packet
+ * Copyright (c) 1997 by Werner Koch (dd9jn)
+ *
+ * This file is part of G10.
+ *
+ * G10 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.
+ *
+ * G10 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include "util.h"
+#include "memory.h"
+#include "packet.h"
+#include "mpi.h"
+#include "cipher.h"
+
+
+static int decode_filter( void *opaque, int control, IOBUF a,
+ byte *buf, size_t *ret_len);
+
+typedef struct {
+ BLOWFISH_context *bf_ctx;
+} decode_filter_ctx_t;
+
+
+
+/****************
+ * Decrypt the data, specified by ED with the key DEK.
+ */
+int
+decrypt_data( PKT_encr_data *ed, DEK *dek )
+{
+ decode_filter_ctx_t dfx;
+ byte *p;
+ int c, i;
+ byte temp[16];
+
+
+ if( dek->algo != CIPHER_ALGO_BLOWFISH )
+ return G10ERR_CIPHER_ALGO;
+ if( ed->len && ed->len < 10 )
+ log_bug("Nanu\n"); /* oops: found a bug */
+
+ dfx.bf_ctx = m_alloc_secure( sizeof *dfx.bf_ctx );
+ blowfish_setkey( dfx.bf_ctx, dek->key, dek->keylen );
+ blowfish_setiv( dfx.bf_ctx, NULL );
+
+ if( ed->len ) {
+ iobuf_set_limit( ed->buf, ed->len );
+
+ for(i=0; i < 10 && ed->len; i++, ed->len-- )
+ temp[i] = iobuf_get(ed->buf);
+ }
+ else {
+ for(i=0; i < 10; i++ )
+ if( (c=iobuf_get(ed->buf)) == -1 )
+ break;
+ else
+ temp[i] = c;
+ }
+ blowfish_decode_cfb( dfx.bf_ctx, temp, temp, 10);
+ p = temp;
+ if( p[6] != p[8] || p[7] != p[9] ) {
+ m_free(dfx.bf_ctx);
+ return G10ERR_BAD_KEY;
+ }
+ iobuf_push_filter( ed->buf, decode_filter, &dfx );
+ proc_packets(ed->buf);
+ iobuf_pop_filter( ed->buf, decode_filter, &dfx );
+ if( ed->len )
+ iobuf_set_limit( ed->buf, 0 ); /* disable the readlimit */
+ else
+ iobuf_clear_eof( ed->buf );
+ ed->buf = NULL;
+ m_free(dfx.bf_ctx);
+ return 0;
+}
+
+static int
+decode_filter( void *opaque, int control, IOBUF a, byte *buf, size_t *ret_len)
+{
+ decode_filter_ctx_t *fc = opaque;
+ size_t n, size = *ret_len;
+ int rc = 0;
+ int c;
+
+ if( control == IOBUFCTRL_UNDERFLOW ) {
+ assert(a);
+ for(n=0; n < size; n++ ) {
+ if( (c = iobuf_get(a)) == -1 )
+ break;
+ buf[n] = c;
+ }
+
+ if( n )
+ blowfish_decode_cfb( fc->bf_ctx, buf, buf, n);
+ else
+ rc = -1; /* eof */
+ *ret_len = n;
+ }
+ else if( control == IOBUFCTRL_DESC ) {
+ *(char**)buf = "decode_filter";
+ }
+ return rc;
+}
+
+