1 /*
2  * lftp - file transfer program
3  *
4  * Copyright (c) 1996-2016 by Alexander V. Lukyanov (lav@yars.free.net)
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #ifndef LFTP_SSL_H
21 #define LFTP_SSL_H
22 
23 #if USE_SSL
24 # if USE_GNUTLS
25 #  include <gnutls/gnutls.h>
26 # elif USE_OPENSSL
27 #  include <openssl/ssl.h>
28 #  include <openssl/err.h>
29 #  include <openssl/rand.h>
30 #  include <openssl/x509v3.h>
31 #  include <openssl/x509_vfy.h>
32 # endif
33 
34 #include "Ref.h"
35 #include "xstring.h"
36 
37 class lftp_ssl_base
38 {
39 public:
40    bool handshake_done;
41    int fd;
42    xstring_c hostname;
43    enum handshake_mode_t { CLIENT, SERVER } handshake_mode;
44    xstring error;
45    bool fatal;
46    bool cert_error;
47 
48    lftp_ssl_base(int fd,handshake_mode_t m,const char *host=0);
49 
50    enum code { RETRY=-2, ERROR=-1, DONE=0 };
51 
52    void set_error(const char *s1,const char *s2);
53    void set_cert_error(const char *s,const xstring& fp);
54 };
55 
56 #if USE_GNUTLS
57 
58 #include <gnutls/x509.h>
59 
60 #if LFTP_LIBGNUTLS_VERSION_CODE < 0x010201
61 /* Compatibility defintions for old gnutls */
62 typedef gnutls_session gnutls_session_t;
63 typedef gnutls_anon_server_credentials gnutls_anon_server_credentials_t;
64 typedef gnutls_dh_params gnutls_dh_params_t;
65 typedef gnutls_certificate_credentials gnutls_certificate_credentials_t;
66 typedef gnutls_transport_ptr gnutls_transport_ptr_t;
67 typedef gnutls_x509_crt gnutls_x509_crt_t;
68 typedef gnutls_x509_crl gnutls_x509_crl_t;
69 typedef gnutls_x509_crt_fmt gnutls_x509_crt_fmt_t;
70 typedef gnutls_datum gnutls_datum_t;
71 #endif
72 
73 #include "ResMgr.h"
74 class lftp_ssl_gnutls_instance : public ResClient
75 {
76    gnutls_x509_crl_t *crl_list;
77    unsigned crl_list_size;
78    gnutls_x509_crt_t *ca_list;
79    unsigned ca_list_size;
80    friend class lftp_ssl_gnutls;
81 
82    void LoadCA();
83    void LoadCRL();
84 public:
85    lftp_ssl_gnutls_instance();
86    ~lftp_ssl_gnutls_instance();
87    void Reconfig(const char *);
88 };
89 class lftp_ssl_gnutls : public lftp_ssl_base
90 {
91    static Ref<lftp_ssl_gnutls_instance> instance;
92    gnutls_session_t session;
93    gnutls_certificate_credentials_t cred;
94    void verify_certificate_chain(const gnutls_datum_t *cert_chain,int cert_chain_length);
95    void verify_cert2(gnutls_x509_crt_t crt,gnutls_x509_crt_t issuer);
96    void verify_last_cert(gnutls_x509_crt_t crt);
97    int do_handshake();
98    bool check_fatal(int res);
99    static const xstring& get_fp(gnutls_x509_crt_t crt);
100 public:
101    static void global_init();
102    static void global_deinit();
103 
104    lftp_ssl_gnutls(int fd,handshake_mode_t m,const char *host=0);
105    ~lftp_ssl_gnutls();
106 
107    int read(char *buf,int size);
108    int write(const char *buf,int size);
109    bool want_in();
110    bool want_out();
111    void copy_sid(const lftp_ssl_gnutls *);
112    void load_keys();
113    void shutdown();
114 };
115 typedef lftp_ssl_gnutls lftp_ssl;
116 #elif USE_OPENSSL
117 class lftp_ssl_openssl_instance {
118 public:
119    SSL_CTX *ssl_ctx;
120    X509_STORE *crl_store;
121    lftp_ssl_openssl_instance();
122    ~lftp_ssl_openssl_instance();
123 };
124 class lftp_ssl_openssl : public lftp_ssl_base
125 {
126    static Ref<lftp_ssl_openssl_instance> instance;
127    SSL *ssl;
128    bool check_fatal(int res);
129    int do_handshake();
130    const char *strerror();
131    static const xstring& get_fp(X509 *crt);
132 public:
133    static int verify_crl(X509_STORE_CTX *ctx);
134    static int verify_callback(int ok,X509_STORE_CTX *ctx);
135    void check_certificate();
136 
137    static void global_init();
138    static void global_deinit();
139 
140    lftp_ssl_openssl(int fd,handshake_mode_t m,const char *host=0);
141    ~lftp_ssl_openssl();
142 
143    int read(char *buf,int size);
144    int write(const char *buf,int size);
145    bool want_in();
146    bool want_out();
147    void copy_sid(const lftp_ssl_openssl *);
148    void load_keys();
149    void shutdown();
150 };
151 typedef lftp_ssl_openssl lftp_ssl;
152 #endif
153 
154 #endif//USE_SSL
155 
156 #endif//LFTP_SSL_H
157