diff options
author | Thomas Roessler <roessler@does-not-exist.org> | 2000-08-30 10:07:23 +0000 |
---|---|---|
committer | Thomas Roessler <roessler@does-not-exist.org> | 2000-08-30 10:07:23 +0000 |
commit | cd5fe3762a4efd163d7e673e68d92dcef1d88969 (patch) | |
tree | a6300e88a1199d64df5de6729403e29dfd8c210b /imap | |
parent | c120ed2848eb3c59a320804f21d2b3fdd075f25b (diff) |
SSL unification patch from Vsevolod.
Diffstat (limited to 'imap')
-rw-r--r-- | imap/Makefile.am | 14 | ||||
-rw-r--r-- | imap/imap_ssl.c | 548 | ||||
-rw-r--r-- | imap/imap_ssl.h | 29 | ||||
-rw-r--r-- | imap/md5.h | 56 | ||||
-rw-r--r-- | imap/md5c.c | 330 | ||||
-rw-r--r-- | imap/util.c | 2 |
6 files changed, 5 insertions, 974 deletions
diff --git a/imap/Makefile.am b/imap/Makefile.am index 2321cb60..bbf773b4 100644 --- a/imap/Makefile.am +++ b/imap/Makefile.am @@ -11,22 +11,16 @@ endif if USE_SASL AUTHENTICATORS = auth_sasl.c else -AUTHENTICATORS = auth_anon.c auth_cram.c md5c.c +AUTHENTICATORS = auth_anon.c auth_cram.c endif -if USE_SSL -SSLSOURCES = imap_ssl.c -SSLHEADERS = imap_ssl.h -endif - -EXTRA_DIST = BUGS README TODO imap_ssl.c imap_ssl.h auth_anon.c \ - auth_cram.c auth_gss.c auth_sasl.c md5c.c +EXTRA_DIST = BUGS README TODO auth_anon.c auth_cram.c auth_gss.c auth_sasl.c INCLUDES = -I$(top_srcdir) -I../intl noinst_LIBRARIES = libimap.a -noinst_HEADERS = auth.h imap_private.h md5.h message.h $(SSLHEADERS) +noinst_HEADERS = auth.h imap_private.h message.h libimap_a_SOURCES = auth.c auth_login.c browse.c command.c imap.c imap.h \ - message.c utf7.c util.c $(AUTHENTICATORS) $(SSLSOURCES) $(GSSSOURCES) + message.c utf7.c util.c $(AUTHENTICATORS) $(GSSSOURCES) diff --git a/imap/imap_ssl.c b/imap/imap_ssl.c deleted file mode 100644 index 6d362ff6..00000000 --- a/imap/imap_ssl.c +++ /dev/null @@ -1,548 +0,0 @@ -/* - * Copyright (C) 1999-2000 Tommi Komulainen <Tommi.Komulainen@iki.fi> - * - * This program 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. - * - * This program 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, USA. - */ - -/* for SSL NO_* defines */ -#include "config.h" - -#include <openssl/ssl.h> -#include <openssl/x509.h> -#include <openssl/err.h> -#include <openssl/rand.h> - -#undef _ - -#include <string.h> - -#include "mutt.h" -#include "imap.h" -#include "imap_private.h" -#include "mutt_socket.h" -#include "mutt_menu.h" -#include "mutt_curses.h" -#include "imap_ssl.h" - -#if OPENSSL_VERSION_NUMBER >= 0x00904000L -#define READ_X509_KEY(fp, key) PEM_read_X509(fp, key, NULL, NULL) -#else -#define READ_X509_KEY(fp, key) PEM_read_X509(fp, key, NULL) -#endif - -/* Just in case OpenSSL doesn't define DEVRANDOM */ -#ifndef DEVRANDOM -#define DEVRANDOM "/dev/urandom" -#endif - -/* This is ugly, but as RAND_status came in on OpenSSL version 0.9.5 - * and the code has to support older versions too, this is seemed to - * be cleaner way compared to having even uglier #ifdefs all around. - */ -#ifdef HAVE_RAND_STATUS -#define HAVE_ENTROPY() (RAND_status() == 1) -#else -static int entropy_byte_count = 0; -/* OpenSSL fills the entropy pool from /dev/urandom if it exists */ -#define HAVE_ENTROPY() (!access(DEVRANDOM, R_OK) || entropy_byte_count >= 16) -#endif - -char *SslCertFile = NULL; -char *SslEntropyFile = NULL; - -typedef struct _sslsockdata -{ - SSL_CTX *ctx; - SSL *ssl; - X509 *cert; -} -sslsockdata; - -static int add_entropy (const char *file); -/* - * OpenSSL library needs to be fed with sufficient entropy. On systems - * with /dev/urandom, this is done transparently by the library itself, - * on other systems we need to fill the entropy pool ourselves. - * - * Even though only OpenSSL 0.9.5 and later will complain about the - * lack of entropy, we try to our best and fill the pool with older - * versions also. (That's the reason for the ugly #ifdefs and macros, - * otherwise I could have simply #ifdef'd the whole ssl_init funcion) - */ -int ssl_init (void) -{ - char path[_POSIX_PATH_MAX]; - - if (HAVE_ENTROPY()) return 0; - - /* load entropy from files */ - add_entropy (SslEntropyFile); - add_entropy (RAND_file_name (path, sizeof (path))); - - /* load entropy from egd sockets */ -#ifdef HAVE_RAND_EGD - add_entropy (getenv ("EGDSOCKET")); - snprintf (path, sizeof(path), "%s/.entropy", NONULL(Homedir)); - add_entropy (path); - add_entropy ("/tmp/entropy"); -#endif - - /* shuffle $RANDFILE (or ~/.rnd if unset) */ - RAND_write_file (RAND_file_name (path, sizeof (path))); - mutt_clear_error (); - if (HAVE_ENTROPY()) return 0; - - mutt_error (_("Failed to find enough entropy on your system")); - sleep (2); - return -1; -} - -static int add_entropy (const char *file) -{ - struct stat st; - int n = -1; - - if (!file) return 0; - - if (stat (file, &st) == -1) - return errno == ENOENT ? 0 : -1; - - mutt_message (_("Filling entropy pool: %s...\n"), - file); - - /* check that the file permissions are secure */ - if (st.st_uid != getuid () || - ((st.st_mode & (S_IWGRP | S_IRGRP)) != 0) || - ((st.st_mode & (S_IWOTH | S_IROTH)) != 0)) - { - mutt_error (_("%s has insecure permissions!"), file); - sleep (2); - return -1; - } - -#ifdef HAVE_RAND_EGD - n = RAND_egd (file); -#endif - if (n <= 0) - n = RAND_load_file (file, -1); - -#ifndef HAVE_RAND_STATUS - if (n > 0) entropy_byte_count += n; -#endif - return n; -} - -static int ssl_socket_open_err (CONNECTION *conn) -{ - mutt_error (_("SSL disabled due the lack of entropy")); - sleep (2); - return -1; -} - -static int ssl_check_certificate (sslsockdata * data); - -static int ssl_socket_read (CONNECTION * conn); -static int ssl_socket_write (CONNECTION* conn, const char* buf, size_t len); -static int ssl_socket_open (CONNECTION * conn); -static int ssl_socket_close (CONNECTION * conn); - -int ssl_socket_setup (CONNECTION * conn) -{ - if (ssl_init() < 0) - { - conn->open = ssl_socket_open_err; - return -1; - } - - conn->open = ssl_socket_open; - conn->read = ssl_socket_read; - conn->write = ssl_socket_write; - conn->close = ssl_socket_close; - - return 0; -} - -int ssl_socket_read (CONNECTION * conn) -{ - sslsockdata *data = conn->sockdata; - return SSL_read (data->ssl, conn->inbuf, LONG_STRING); -} - -int ssl_socket_write (CONNECTION* conn, const char* buf, size_t len) -{ - sslsockdata *data = conn->sockdata; - return SSL_write (data->ssl, buf, len); -} - -int ssl_socket_open (CONNECTION * conn) -{ - sslsockdata *data; - int err; - - if (raw_socket_open (conn) < 0) - return -1; - - data = (sslsockdata *) safe_calloc (1, sizeof (sslsockdata)); - conn->sockdata = data; - - SSL_library_init(); - data->ctx = SSL_CTX_new (SSLv23_client_method ()); - - /* disable SSL protocols as needed */ - if (!option(OPTTLSV1)) - { - SSL_CTX_set_options(data->ctx, SSL_OP_NO_TLSv1); - } - if (!option(OPTSSLV2)) - { - SSL_CTX_set_options(data->ctx, SSL_OP_NO_SSLv2); - } - if (!option(OPTSSLV3)) - { - SSL_CTX_set_options(data->ctx, SSL_OP_NO_SSLv3); - } - - data->ssl = SSL_new (data->ctx); - SSL_set_fd (data->ssl, conn->fd); - - if ((err = SSL_connect (data->ssl)) < 0) - { - ssl_socket_close (conn); - return -1; - } - - data->cert = SSL_get_peer_certificate (data->ssl); - if (!data->cert) - { - mutt_error (_("Unable to get certificate from peer")); - sleep (1); - return -1; - } - - if (!ssl_check_certificate (data)) - { - ssl_socket_close (conn); - return -1; - } - - mutt_message (_("SSL connection using %s"), SSL_get_cipher (data->ssl)); - sleep (1); - - return 0; -} - -int ssl_socket_close (CONNECTION * conn) -{ - sslsockdata *data = conn->sockdata; - if (data) - { - SSL_shutdown (data->ssl); - - X509_free (data->cert); - SSL_free (data->ssl); - SSL_CTX_free (data->ctx); - safe_free ((void **) &conn->sockdata); - } - - return raw_socket_close (conn); -} - - - -static char *x509_get_part (char *line, const char *ndx) -{ - static char ret[SHORT_STRING]; - char *c, *c2; - - strncpy (ret, _("Unknown"), sizeof (ret)); - - c = strstr (line, ndx); - if (c) - { - c += strlen (ndx); - c2 = strchr (c, '/'); - if (c2) - *c2 = '\0'; - strncpy (ret, c, sizeof (ret)); - if (c2) - *c2 = '/'; - } - - return ret; -} - -static void x509_fingerprint (char *s, int l, X509 * cert) -{ - unsigned char md[EVP_MAX_MD_SIZE]; - unsigned int n; - int j; - - if (!X509_digest (cert, EVP_md5 (), md, &n)) - { - snprintf (s, l, _("[unable to calculate]")); - } - else - { - for (j = 0; j < (int) n; j++) - { - char ch[8]; - snprintf (ch, 8, "%02X%s", md[j], (j % 2 ? " " : "")); - strncat (s, ch, l); - } - } -} - -static char *asn1time_to_string (ASN1_UTCTIME *tm) -{ - static char buf[64]; - BIO *bio; - - strncpy (buf, _("[invalid date]"), sizeof (buf)); - - bio = BIO_new (BIO_s_mem()); - if (bio) - { - if (ASN1_TIME_print (bio, tm)) - (void) BIO_read (bio, buf, sizeof (buf)); - BIO_free (bio); - } - - return buf; -} - -static int check_certificate_by_signer (X509 *peercert) -{ - X509_STORE_CTX xsc; - X509_STORE *ctx; - int pass = 0; - - ctx = X509_STORE_new (); - if (ctx == NULL) return 0; - - if (option (OPTSSLSYSTEMCERTS)) - { - if (X509_STORE_set_default_paths (ctx)) - pass++; - else - dprint (2, (debugfile, "X509_STORE_set_default_paths failed\n")); - } - - if (X509_STORE_load_locations (ctx, SslCertFile, NULL)) - pass++; - else - dprint (2, (debugfile, "X509_STORE_load_locations_failed\n")); - - if (pass == 0) - { - /* nothing to do */ - X509_STORE_free (ctx); - return 0; - } - - X509_STORE_CTX_init (&xsc, ctx, peercert, NULL); - - pass = (X509_verify_cert (&xsc) > 0); -#ifdef DEBUG - if (! pass) - { - char buf[SHORT_STRING]; - int err; - - err = X509_STORE_CTX_get_error (&xsc); - snprintf (buf, sizeof (buf), "%s (%d)", - X509_verify_cert_error_string(err), err); - dprint (2, (debugfile, "X509_verify_cert: %s\n", buf)); - } -#endif - X509_STORE_CTX_cleanup (&xsc); - X509_STORE_free (ctx); - - return pass; -} - -static int check_certificate_by_digest (X509 *peercert) -{ - unsigned char peermd[EVP_MAX_MD_SIZE]; - unsigned int peermdlen; - X509 *cert = NULL; - int pass = 0; - FILE *fp; - - /* expiration check */ - if (X509_cmp_current_time (X509_get_notBefore (peercert)) >= 0) - { - dprint (2, (debugfile, "Server certificate is not yet valid\n")); - mutt_error (_("Server certificate is not yet valid")); - sleep (2); - return 0; - } - if (X509_cmp_current_time (X509_get_notAfter (peercert)) <= 0) - { - dprint (2, (debugfile, "Server certificate has expired")); - mutt_error (_("Server certificate has expired")); - sleep (2); - return 0; - } - - if ((fp = fopen (SslCertFile, "rt")) == NULL) - return 0; - - if (!X509_digest (peercert, EVP_sha1(), peermd, &peermdlen)) - { - fclose (fp); - return 0; - } - - while ((cert = READ_X509_KEY (fp, &cert)) != NULL) - { - unsigned char md[EVP_MAX_MD_SIZE]; - unsigned int mdlen; - - /* Avoid CPU-intensive digest calculation if the certificates are - * not even remotely equal. - */ - if (X509_subject_name_cmp (cert, peercert) != 0 || - X509_issuer_name_cmp (cert, peercert) != 0) - continue; - - if (!X509_digest (cert, EVP_sha1(), md, &mdlen) || peermdlen != mdlen) - continue; - - if (memcmp(peermd, md, mdlen) != 0) - continue; - - pass = 1; - break; - } - X509_free (cert); - fclose (fp); - - return pass; -} - -static int ssl_check_certificate (sslsockdata * data) -{ - char *part[] = - {"/CN=", "/Email=", "/O=", "/OU=", "/L=", "/ST=", "/C="}; - char helpstr[SHORT_STRING]; - char buf[SHORT_STRING]; - MUTTMENU *menu; - int done, row, i; - FILE *fp; - char *name = NULL, *c; - - if (check_certificate_by_signer (data->cert)) - { - dprint (1, (debugfile, "ssl_check_certificate: signer check passed\n")); - return 1; - } - - /* automatic check from user's database */ - if (SslCertFile && check_certificate_by_digest (data->cert)) - { - dprint (1, (debugfile, "ssl_check_certificate: digest check passed\n")); - return 1; - } - - /* interactive check from user */ - menu = mutt_new_menu (); - menu->max = 19; - menu->dialog = (char **) safe_calloc (1, menu->max * sizeof (char *)); - for (i = 0; i < menu->max; i++) - menu->dialog[i] = (char *) safe_calloc (1, SHORT_STRING * sizeof (char)); - - row = 0; - strncpy (menu->dialog[row++], _("This certificate belongs to:"), SHORT_STRING); - name = X509_NAME_oneline (X509_get_subject_name (data->cert), - buf, sizeof (buf)); - for (i = 0; i < 5; i++) - { - c = x509_get_part (name, part[i]); - snprintf (menu->dialog[row++], SHORT_STRING, " %s", c); - } - - row++; - strncpy (menu->dialog[row++], _("This certificate was issued by:"), SHORT_STRING); - name = X509_NAME_oneline (X509_get_issuer_name (data->cert), - buf, sizeof (buf)); - for (i = 0; i < 5; i++) - { - c = x509_get_part (name, part[i]); - snprintf (menu->dialog[row++], SHORT_STRING, " %s", c); - } - - row++; - snprintf (menu->dialog[row++], SHORT_STRING, _("This certificate is valid")); - snprintf (menu->dialog[row++], SHORT_STRING, _(" from %s"), - asn1time_to_string (X509_get_notBefore (data->cert))); - snprintf (menu->dialog[row++], SHORT_STRING, _(" to %s"), - asn1time_to_string (X509_get_notAfter (data->cert))); - - row++; - buf[0] = '\0'; - x509_fingerprint (buf, sizeof (buf), data->cert); - snprintf (menu->dialog[row++], SHORT_STRING, _("Fingerprint: %s"), buf); - - menu->title = _("SSL Certificate check"); - if (SslCertFile) - { - menu->prompt = _("(r)eject, accept (o)nce, (a)ccept always"); - menu->keys = _("roa"); - } - else - { - menu->prompt = _("(r)eject, accept (o)nce"); - menu->keys = _("ro"); - } - - helpstr[0] = '\0'; - mutt_make_help (buf, sizeof (buf), _("Exit "), MENU_GENERIC, OP_EXIT); - strncat (helpstr, buf, sizeof (helpstr)); - mutt_make_help (buf, sizeof (buf), _("Help"), MENU_GENERIC, OP_HELP); - strncat (helpstr, buf, sizeof (helpstr)); - menu->help = helpstr; - - done = 0; - while (!done) - { - switch (mutt_menuLoop (menu)) - { - case -1: /* abort */ - case OP_MAX + 1: /* reject */ - case OP_EXIT: - done = 1; - break; - case OP_MAX + 3: /* accept always */ - done = 0; - if ((fp = fopen (SslCertFile, "a"))) - { - if (PEM_write_X509 (fp, data->cert)) - done = 1; - fclose (fp); - } - if (!done) - mutt_error (_("Warning: Couldn't save certificate")); - else - mutt_message (_("Certificate saved")); - sleep (1); - /* fall through */ - case OP_MAX + 2: /* accept once */ - done = 2; - break; - } - } - mutt_menuDestroy (&menu); - return (done == 2); -} diff --git a/imap/imap_ssl.h b/imap/imap_ssl.h deleted file mode 100644 index 575580a3..00000000 --- a/imap/imap_ssl.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (C) 1999-2000 Tommi Komulainen <Tommi.Komulainen@iki.fi> - * - * This program 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. - * - * This program 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, USA. - */ - -#ifndef _MUTT_SSL_H_ -#define _MUTT_SSL_H_ 1 - -#include "mutt_socket.h" - -extern char *SslCertFile; -extern char *SslEntropyFile; - -extern int ssl_socket_setup (CONNECTION *conn); - -#endif /* _MUTT_SSL_H_ */ diff --git a/imap/md5.h b/imap/md5.h deleted file mode 100644 index e0b70191..00000000 --- a/imap/md5.h +++ /dev/null @@ -1,56 +0,0 @@ -/* MD5.H - header file for MD5C.C - */ - -/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All -rights reserved. - -License to copy and use this software is granted provided that it -is identified as the "RSA Data Security, Inc. MD5 Message-Digest -Algorithm" in all material mentioning or referencing this software -or this function. - -License is also granted to make and use derivative works provided -that such works are identified as "derived from the RSA Data -Security, Inc. MD5 Message-Digest Algorithm" in all material -mentioning or referencing the derived work. - -RSA Data Security, Inc. makes no representations concerning either -the merchantability of this software or the suitability of this -software for any particular purpose. It is provided "as is" -without express or implied warranty of any kind. - -These notices must be retained in any copies of any part of this -documentation and/or software. - */ - -#ifndef MD5_H -#define MD5_H 1 - - -/* POINTER defines a generic pointer type */ -typedef unsigned char *POINTER; - -#include "types.h" - -#if 0 - -/* UINT2 defines a two byte word */ -typedef unsigned short int UINT2; - -/* UINT4 defines a four byte word */ -typedef unsigned long int UINT4; - -#endif - -/* MD5 context. */ -typedef struct { - UINT4 state[4]; /* state (ABCD) */ - UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */ - unsigned char buffer[64]; /* input buffer */ -} MD5_CTX; - -void MD5Init (MD5_CTX *); -void MD5Update (MD5_CTX *, unsigned char *, unsigned int); -void MD5Final (unsigned char [16], MD5_CTX *); - -#endif diff --git a/imap/md5c.c b/imap/md5c.c deleted file mode 100644 index b1e78ce5..00000000 --- a/imap/md5c.c +++ /dev/null @@ -1,330 +0,0 @@ -/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm - */ - -/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All -rights reserved. - -License to copy and use this software is granted provided that it -is identified as the "RSA Data Security, Inc. MD5 Message-Digest -Algorithm" in all material mentioning or referencing this software -or this function. - -License is also granted to make and use derivative works provided -that such works are identified as "derived from the RSA Data -Security, Inc. MD5 Message-Digest Algorithm" in all material -mentioning or referencing the derived work. - -RSA Data Security, Inc. makes no representations concerning either -the merchantability of this software or the suitability of this -software for any particular purpose. It is provided "as is" -without express or implied warranty of any kind. - -These notices must be retained in any copies of any part of this -documentation and/or software. - */ - -#include "md5.h" - -/* Constants for MD5Transform routine. - */ - -#define S11 7 -#define S12 12 -#define S13 17 -#define S14 22 -#define S21 5 -#define S22 9 -#define S23 14 -#define S24 20 -#define S31 4 -#define S32 11 -#define S33 16 -#define S34 23 -#define S41 6 -#define S42 10 -#define S43 15 -#define S44 21 - -static void MD5Transform (UINT4 [4], unsigned char [64]); -static void Encode (unsigned char *, UINT4 *, unsigned int); -static void Decode (UINT4 *, unsigned char *, unsigned int); -static void MD5_memcpy (POINTER, POINTER, unsigned int); -static void MD5_memset (POINTER, int, unsigned int); - -static unsigned char PADDING[64] = { - 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; - -/* F, G, H and I are basic MD5 functions. - */ -#define F(x, y, z) (((x) & (y)) | ((~x) & (z))) -#define G(x, y, z) (((x) & (z)) | ((y) & (~z))) -#define H(x, y, z) ((x) ^ (y) ^ (z)) -#define I(x, y, z) ((y) ^ ((x) | (~z))) - -/* ROTATE_LEFT rotates x left n bits. - */ -#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) - -/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. -Rotation is separate from addition to prevent recomputation. - */ -#define FF(a, b, c, d, x, s, ac) { \ - (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \ - (a) = ROTATE_LEFT ((a), (s)); \ - (a) += (b); \ - } -#define GG(a, b, c, d, x, s, ac) { \ - (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \ - (a) = ROTATE_LEFT ((a), (s)); \ - (a) += (b); \ - } -#define HH(a, b, c, d, x, s, ac) { \ - (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \ - (a) = ROTATE_LEFT ((a), (s)); \ - (a) += (b); \ - } -#define II(a, b, c, d, x, s, ac) { \ - (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \ - (a) = ROTATE_LEFT ((a), (s)); \ - (a) += (b); \ - } - -/* MD5 initialization. Begins an MD5 operation, writing a new context. - */ -void MD5Init (context) -MD5_CTX *context; /* context */ -{ - context->count[0] = context->count[1] = 0; - /* Load magic initialization constants. -*/ - context->state[0] = 0x67452301; - context->state[1] = 0xefcdab89; - context->state[2] = 0x98badcfe; - context->state[3] = 0x10325476; -} - -/* MD5 block update operation. Continues an MD5 message-digest - operation, processing another message block, and updating the - context. - */ -void MD5Update (context, input, inputLen) -MD5_CTX *context; /* context */ -unsigned char *input; /* input block */ -unsigned int inputLen; /* length of input block */ -{ - unsigned int i, index, partLen; - - /* Compute number of bytes mod 64 */ - index = (unsigned int)((context->count[0] >> 3) & 0x3F); - - /* Update number of bits */ - if ((context->count[0] += ((UINT4)inputLen << 3)) - < ((UINT4)inputLen << 3)) - context->count[1]++; - context->count[1] += ((UINT4)inputLen >> 29); - - partLen = 64 - index; - - /* Transform as many times as possible. -*/ - if (inputLen >= partLen) { - MD5_memcpy - ((POINTER)&context->buffer[index], (POINTER)input, partLen); - MD5Transform (context->state, context->buffer); - - for (i = partLen; i + 63 < inputLen; i += 64) - MD5Transform (context->state, &input[i]); - - index = 0; - } - else - i = 0; - - /* Buffer remaining input */ - MD5_memcpy - ((POINTER)&context->buffer[index], (POINTER)&input[i], - inputLen-i); -} - -/* MD5 finalization. Ends an MD5 message-digest operation, writing the - the message digest and zeroizing the context. - */ -void MD5Final (digest, context) -unsigned char digest[16]; /* message digest */ -MD5_CTX *context; /* context */ -{ - unsigned char bits[8]; - unsigned int index, padLen; - - /* Save number of bits */ - Encode (bits, context->count, 8); - - /* Pad out to 56 mod 64. -*/ - index = (unsigned int)((context->count[0] >> 3) & 0x3f); - padLen = (index < 56) ? (56 - index) : (120 - index); - MD5Update (context, PADDING, padLen); - - /* Append length (before padding) */ - MD5Update (context, bits, 8); - /* Store state in digest */ - Encode (digest, context->state, 16); - - /* Zeroize sensitive information. -*/ - MD5_memset ((POINTER)context, 0, sizeof (*context)); -} - -/* MD5 basic transformation. Transforms state based on block. - */ -static void MD5Transform (state, block) -UINT4 state[4]; -unsigned char block[64]; -{ - UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16]; - - Decode (x, block, 64); - - /* Round 1 */ - FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */ - FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */ - FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */ - FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */ - FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */ - FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */ - FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */ - FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */ - FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */ - FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */ - FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */ - FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */ - FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */ - FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */ - FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */ - FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */ - - /* Round 2 */ - GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */ - GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */ - GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */ - GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */ - GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */ - GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */ - GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */ - GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */ - GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */ - GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */ - GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */ - GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */ - GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ - GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */ - GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */ - GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ - - /* Round 3 */ - HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */ - HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */ - HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */ - HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */ - HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */ - HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */ - HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */ - HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */ - HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */ - HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */ - HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */ - HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */ - HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */ - HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */ - HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */ - HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */ - - /* Round 4 */ - II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */ - II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */ - II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */ - II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */ - II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */ - II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */ - II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */ - II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */ - II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */ - II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */ - II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */ - II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */ - II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */ - II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */ - II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */ - II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */ - - state[0] += a; - state[1] += b; - state[2] += c; - state[3] += d; - - /* Zeroize sensitive information. */ - MD5_memset ((POINTER)x, 0, sizeof (x)); -} - -/* Encodes input (UINT4) into output (unsigned char). Assumes len is - a multiple of 4. - */ -static void Encode (output, input, len) -unsigned char *output; -UINT4 *input; -unsigned int len; -{ - unsigned int i, j; - - for (i = 0, j = 0; j < len; i++, j += 4) { - output[j] = (unsigned char)(input[i] & 0xff); - output[j+1] = (unsigned char)((input[i] >> 8) & 0xff); - output[j+2] = (unsigned char)((input[i] >> 16) & 0xff); - output[j+3] = (unsigned char)((input[i] >> 24) & 0xff); - } -} - -/* Decodes input (unsigned char) into output (UINT4). Assumes len is - a multiple of 4. - */ -static void Decode (output, input, len) -UINT4 *output; -unsigned char *input; -unsigned int len; -{ - unsigned int i, j; - - for (i = 0, j = 0; j < len; i++, j += 4) - output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) | - (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24); -} - -/* Note: Replace "for loop" with standard memcpy if possible. - */ - -static void MD5_memcpy (output, input, len) -POINTER output; -POINTER input; -unsigned int len; -{ - unsigned int i; - - for (i = 0; i < len; i++) - output[i] = input[i]; -} - -/* Note: Replace "for loop" with standard memset if possible. - */ -static void MD5_memset (output, value, len) -POINTER output; -int value; -unsigned int len; -{ - unsigned int i; - - for (i = 0; i < len; i++) - ((char *)output)[i] = (char)value; -} diff --git a/imap/util.c b/imap/util.c index ecd346dd..fdb540b0 100644 --- a/imap/util.c +++ b/imap/util.c @@ -24,7 +24,7 @@ #include "mx.h" /* for M_IMAP */ #include "url.h" #include "imap_private.h" -#include "imap_ssl.h" +#include "mutt_ssl.h" #include <stdlib.h> #include <ctype.h> |