3 Minimal CyaSSL/OpenSSL Helper
4 Copyright (C) 2006-2009 Jonathan Zarate
5 Copyright (C) 2010 Fedor Kozhevnikov
7 Licensed under GNU GPL v2 or later
23 #include <openssl/ssl.h>
24 #include <openssl/err.h>
27 #include <openssl/rsa.h>
28 #include <openssl/crypto.h>
29 #include <openssl/x509.h>
30 #include <openssl/pem.h>
32 #include <cyassl_error.h>
35 #define _dprintf(args...) while (0) {}
44 static inline void mssl_print_err(SSL
* ssl
)
47 ERR_print_errors_fp(stderr
);
49 _dprintf("CyaSSL error %d\n", ssl
? SSL_get_error(ssl
, 0) : -1);
53 static inline void mssl_cleanup(int err
)
55 if (err
) mssl_print_err(NULL
);
60 static ssize_t
mssl_read(void *cookie
, char *buf
, size_t len
)
62 _dprintf("%s()\n", __FUNCTION__
);
64 mssl_cookie_t
*kuki
= cookie
;
69 n
= SSL_read(kuki
->ssl
, &(buf
[total
]), len
- total
);
70 _dprintf("SSL_read(max=%d) returned %d\n", len
- total
, n
);
72 err
= SSL_get_error(kuki
->ssl
, n
);
77 case SSL_ERROR_ZERO_RETURN
:
80 case SSL_ERROR_WANT_WRITE
:
81 case SSL_ERROR_WANT_READ
:
84 _dprintf("%s(): SSL error %d\n", __FUNCTION__
, err
);
85 mssl_print_err(kuki
->ssl
);
86 if (total
== 0) total
= -1;
89 } while ((len
- total
> 0) && SSL_pending(kuki
->ssl
));
92 _dprintf("%s() returns %d\n", __FUNCTION__
, total
);
96 static ssize_t
mssl_write(void *cookie
, const char *buf
, size_t len
)
98 _dprintf("%s()\n", __FUNCTION__
);
100 mssl_cookie_t
*kuki
= cookie
;
104 while (total
< len
) {
105 n
= SSL_write(kuki
->ssl
, &(buf
[total
]), len
- total
);
106 _dprintf("SSL_write(max=%d) returned %d\n", len
- total
, n
);
107 err
= SSL_get_error(kuki
->ssl
, n
);
112 case SSL_ERROR_ZERO_RETURN
:
115 case SSL_ERROR_WANT_WRITE
:
116 case SSL_ERROR_WANT_READ
:
119 _dprintf("%s(): SSL error %d\n", __FUNCTION__
, err
);
120 mssl_print_err(kuki
->ssl
);
121 if (total
== 0) total
= -1;
127 _dprintf("%s() returns %d\n", __FUNCTION__
, total
);
131 static int mssl_seek(void *cookie
, __offmax_t
*pos
, int whence
)
133 _dprintf("%s()\n", __FUNCTION__
);
138 static int mssl_close(void *cookie
)
140 _dprintf("%s()\n", __FUNCTION__
);
142 mssl_cookie_t
*kuki
= cookie
;
146 SSL_shutdown(kuki
->ssl
);
154 static const cookie_io_functions_t mssl
= {
155 mssl_read
, mssl_write
, mssl_seek
, mssl_close
158 static FILE *_ssl_fopen(int sd
, int client
)
164 _dprintf("%s()\n", __FUNCTION__
);
166 if ((kuki
= calloc(1, sizeof(*kuki
))) == NULL
) {
172 if ((kuki
->ssl
= SSL_new(ctx
)) == NULL
) {
173 _dprintf("%s: SSL_new failed\n", __FUNCTION__
);
178 SSL_set_verify(kuki
->ssl
, SSL_VERIFY_NONE
, NULL
);
179 SSL_set_mode(kuki
->ssl
, SSL_MODE_AUTO_RETRY
);
181 SSL_set_fd(kuki
->ssl
, kuki
->sd
);
183 r
= client
? SSL_connect(kuki
->ssl
) : SSL_accept(kuki
->ssl
);
185 _dprintf("%s: SSL handshake failed\n", __FUNCTION__
);
186 mssl_print_err(kuki
->ssl
);
191 _dprintf("SSL connection using %s cipher\n", SSL_get_cipher(kuki
->ssl
));
194 if ((f
= fopencookie(kuki
, "r+", mssl
)) == NULL
) {
195 _dprintf("%s: fopencookie failed\n", __FUNCTION__
);
199 _dprintf("%s() success\n", __FUNCTION__
);
207 FILE *ssl_server_fopen(int sd
)
209 _dprintf("%s()\n", __FUNCTION__
);
210 return _ssl_fopen(sd
, 0);
213 FILE *ssl_client_fopen(int sd
)
215 _dprintf("%s()\n", __FUNCTION__
);
216 return _ssl_fopen(sd
, 1);
219 int mssl_init(char *cert
, char *priv
)
221 _dprintf("%s()\n", __FUNCTION__
);
223 int server
= (cert
!= NULL
);
226 SSL_load_error_strings();
227 SSLeay_add_ssl_algorithms();
230 ctx
= SSL_CTX_new(server
? TLSv1_server_method() : TLSv1_client_method());
232 _dprintf("SSL_CTX_new() failed\n");
233 mssl_print_err(NULL
);
238 SSL_CTX_set_verify(ctx
, SSL_VERIFY_NONE
, NULL
);
242 _dprintf("SSL_CTX_use_certificate_file(%s)\n", cert
);
243 if (SSL_CTX_use_certificate_file(ctx
, cert
, SSL_FILETYPE_PEM
) <= 0) {
244 _dprintf("SSL_CTX_use_certificate_file() failed\n");
248 _dprintf("SSL_CTX_use_PrivateKey_file(%s)\n", priv
);
249 if (SSL_CTX_use_PrivateKey_file(ctx
, priv
, SSL_FILETYPE_PEM
) <= 0) {
250 _dprintf("SSL_CTX_use_PrivateKey_file() failed\n");
255 if (!SSL_CTX_check_private_key(ctx
)) {
256 _dprintf("Private key does not match the certificate public key\n");
263 _dprintf("%s() success\n", __FUNCTION__
);