reverse previous changes
[claws.git] / src / ssl.c
1 /*
2  * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3  * Copyright (C) 1999-2001 Hiroyuki Yamamoto
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18  */
19
20 #ifdef HAVE_CONFIG_H
21 #  include "config.h"
22 #endif
23
24 #if USE_SSL
25
26 #include "intl.h"
27 #include "utils.h"
28 #include "ssl.h"
29
30 SSL_CTX *ssl_ctx_SSLv23;
31 SSL_CTX *ssl_ctx_TLSv1;
32
33 void ssl_init() {
34     SSL_METHOD *meth;
35                 
36     SSL_library_init();
37     SSL_load_error_strings();
38     
39     ssl_ctx_SSLv23 = SSL_CTX_new(SSLv23_client_method());
40     if(ssl_ctx_SSLv23 == NULL) {
41         debug_print(_("SSLv23 not available\n"));
42     } else {
43         debug_print(_("SSLv23 available\n"));
44     }
45
46     ssl_ctx_TLSv1 = SSL_CTX_new(TLSv1_client_method());
47     if(ssl_ctx_TLSv1 == NULL) {
48         debug_print(_("TLSv1 not available\n"));
49     } else {
50         debug_print(_("TLSv1 available\n"));
51     }
52 }
53
54 void ssl_done() {
55     if(ssl_ctx_SSLv23) {
56         SSL_CTX_free(ssl_ctx_SSLv23);
57     }
58
59     if(ssl_ctx_TLSv1) {
60         SSL_CTX_free(ssl_ctx_TLSv1);
61     }
62 }
63
64 gboolean ssl_init_socket(SockInfo *sockinfo) {
65     return ssl_init_socket_with_method(sockinfo, SSL_METHOD_SSLv23);
66 }
67
68 gboolean ssl_init_socket_with_method(SockInfo *sockinfo, SSL_METHODs method) {
69     X509 *server_cert;
70     int ret;
71
72     switch(method) {
73         case SSL_METHOD_SSLv23:
74             if(!ssl_ctx_SSLv23) {
75                 log_warning(_("SSL method not available\n"));
76                 return FALSE;
77             }
78             sockinfo->ssl = SSL_new(ssl_ctx_SSLv23);
79             break;
80         case SSL_METHOD_TLSv1:
81             if(!ssl_ctx_TLSv1) {
82                 log_warning(_("SSL method not available\n"));
83                 return FALSE;
84             }
85             sockinfo->ssl = SSL_new(ssl_ctx_TLSv1);
86             break;
87         default:
88             log_warning(_("Unknown SSL method *PROGRAM BUG*\n"));
89             return FALSE;
90             break;
91     }
92     
93     if(sockinfo->ssl == NULL) {
94         log_warning(_("Error creating ssl context\n"));
95
96         return FALSE;
97     }
98
99     SSL_set_fd(sockinfo->ssl, sockinfo->sock);
100     if((ret = SSL_connect(sockinfo->ssl)) == -1) {
101         log_warning(_("SSL connect failed (%s)\n"), ERR_error_string(ERR_get_error(), NULL));
102
103         return FALSE;
104     }
105
106     /* Get the cipher */
107
108     log_print(_("SSL connection using %s\n"), SSL_get_cipher(sockinfo->ssl));
109
110     /* Get server's certificate (note: beware of dynamic allocation) */
111
112     if((server_cert = SSL_get_peer_certificate(sockinfo->ssl)) != NULL) {
113         char *str;
114         
115         log_print(_("Server certificate:\n"));
116
117         if((str = X509_NAME_oneline(X509_get_subject_name (server_cert),0,0)) != NULL) {
118                 log_print(_("  Subject: %s\n"), str);
119                 free(str);
120         }
121         
122         if((str = X509_NAME_oneline(X509_get_issuer_name  (server_cert),0,0)) != NULL) {
123                 log_print(_("  Issuer: %s\n"), str);
124                 free(str);
125         }
126
127         X509_free(server_cert);
128     }
129     
130     return TRUE;
131 }
132
133 void ssl_done_socket(SockInfo *sockinfo) {
134     if(sockinfo->ssl) {
135         SSL_free(sockinfo->ssl);
136     }
137 }
138
139 #endif /* USE_SSL */