comparison mcabber/connwrap/connwrap.c @ 938:40175f3dcef7

SSL server certificate verification This patch enables SSL server certificate verification.
author Jefferson Ogata <ogata@antibozo.net>
date Sat, 08 Jul 2006 23:32:49 +0200
parents 89aeb8fdd215
children 6be62425dc38
comparison
equal deleted inserted replaced
937:548def60b810 938:40175f3dcef7
31 31
32 #ifdef HAVE_OPENSSL 32 #ifdef HAVE_OPENSSL
33 33
34 static SSL_CTX *ctx = 0; 34 static SSL_CTX *ctx = 0;
35 35
36 /* verify > 0 indicates verify depth as well */
37 static int verify = -1;
38 static const char *cafile = NULL;
39 static const char *capath = NULL;
40 static const char *cipherlist = NULL;
41 static const char *peer = NULL;
42 static const char *sslerror = NULL;
43
44 static int verify_cb(int preverify_ok, X509_STORE_CTX *cx)
45 {
46 X509 *cert;
47 X509_NAME *nm;
48 int lastpos;
49
50 if(!preverify_ok) {
51 long err = X509_STORE_CTX_get_error(cx);
52
53 sslerror = X509_verify_cert_error_string(err);
54 return 0;
55 }
56
57 if (peer == NULL)
58 return 1;
59
60 if ((cert = X509_STORE_CTX_get_current_cert(cx)) == NULL) {
61 sslerror = "internal SSL error";
62 return 0;
63 }
64
65 /* We only want to look at the peername if we're working on the peer
66 * certificate. */
67 if (cert != cx->cert)
68 return 1;
69
70 if ((nm = X509_get_subject_name (cert)) == NULL) {
71 sslerror = "internal SSL error";
72 return 0;
73 }
74
75 for(lastpos = -1; ; ) {
76 X509_NAME_ENTRY *e;
77 ASN1_STRING *a;
78 ASN1_STRING *p;
79 int match;
80
81 lastpos = X509_NAME_get_index_by_NID(nm, NID_commonName, lastpos);
82 if (lastpos == -1)
83 break;
84 if ((e = X509_NAME_get_entry(nm, lastpos)) == NULL) {
85 sslerror = "internal SSL error";
86 return 0;
87 }
88 if ((a = X509_NAME_ENTRY_get_data(e)) == NULL) {
89 sslerror = "internal SSL error";
90 return 0;
91 }
92 if ((p = ASN1_STRING_type_new(ASN1_STRING_type(a))) == NULL) {
93 sslerror = "internal SSL error";
94 return 0;
95 }
96 (void) ASN1_STRING_set(p, peer, -1);
97 match = !ASN1_STRING_cmp(a, p);
98 ASN1_STRING_free(p);
99 if(match)
100 return 1;
101 }
102
103 sslerror = "server certificate cn mismatch";
104 return 0;
105 }
106
107 static void init(void) {
108 if(ctx)
109 return;
110
111 SSL_library_init();
112 SSL_load_error_strings();
113
114 #ifdef HAVE_SSLEAY
115 SSLeay_add_all_algorithms();
116 #else
117 OpenSSL_add_all_algorithms();
118 #endif
119
120 /* May need to use distinct SSLEAY bindings below... */
121
122 //ctx = SSL_CTX_new(SSLv23_method());
123 ctx = SSL_CTX_new(SSLv23_client_method());
124 if(cipherlist)
125 (void)SSL_CTX_set_cipher_list(ctx, cipherlist);
126 if(cafile || capath)
127 (void)SSL_CTX_load_verify_locations(ctx, cafile, capath);
128 if(verify) {
129 SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, verify_cb);
130 if(verify > 0)
131 SSL_CTX_set_verify_depth(ctx, verify);
132 } else
133 SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL);
134 }
135
36 typedef struct { int fd; SSL *ssl; } sslsock; 136 typedef struct { int fd; SSL *ssl; } sslsock;
37 137
38 static sslsock *socks = 0; 138 static sslsock *socks = 0;
39 static int sockcount = 0; 139 static int sockcount = 0;
40 140
52 sslsock *p; 152 sslsock *p;
53 socks = (sslsock *) realloc(socks, sizeof(sslsock)*++sockcount); 153 socks = (sslsock *) realloc(socks, sizeof(sslsock)*++sockcount);
54 154
55 p = &socks[sockcount-1]; 155 p = &socks[sockcount-1];
56 156
57 if(!ctx) { 157 init ();
58 SSL_library_init();
59 SSL_load_error_strings();
60
61 #ifdef HAVE_SSLEAY
62 SSLeay_add_all_algorithms();
63 #else
64 OpenSSL_add_all_algorithms();
65 #endif
66
67 //ctx = SSL_CTX_new(SSLv23_method());
68 ctx = SSL_CTX_new(SSLv23_client_method());
69 }
70 158
71 p->ssl = SSL_new(ctx); 159 p->ssl = SSL_new(ctx);
72 SSL_set_fd(p->ssl, p->fd = fd); 160 SSL_set_fd(p->ssl, p->fd = fd);
161 sslerror = NULL;
73 162
74 return p; 163 return p;
75 } 164 }
76 165
77 static void delsock(int fd) { 166 static void delsock(int fd) {
91 180
92 free(socks); 181 free(socks);
93 182
94 socks = nsocks; 183 socks = nsocks;
95 sockcount = nsockcount; 184 sockcount = nsockcount;
185 }
186
187 void cw_set_ssl_options(int sslverify, const char *sslcafile, const char *sslcapath, const char *sslciphers, const char *sslpeer) {
188 verify = sslverify;
189 cafile = sslcafile;
190 capath = sslcapath;
191 cipherlist = sslciphers;
192 peer = sslpeer;
193 }
194
195 const char *cw_get_ssl_error(void) {
196 return sslerror;
197 }
198
199 #else
200
201 void cw_set_ssl_options(int sslverify, const char *sslcafile, const char *sslcapath, const char *sslciphers, const char *sslpeer) { }
202
203 const char *cw_get_ssl_error(void) {
204 return NULL;
96 } 205 }
97 206
98 #endif 207 #endif
99 208
100 static char *bindaddr = 0, *proxyhost = 0, *proxyuser = 0, *proxypass = 0; 209 static char *bindaddr = 0, *proxyhost = 0, *proxyuser = 0, *proxypass = 0;