Mercurial > ~mikael > mcabber > hg
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; |