]> git.sur5r.net Git - bacula/docs/blob - docs/developers/tls-techdoc.tex
- Create French and Italian translation files (fr.po, it.po).
[bacula/docs] / docs / developers / tls-techdoc.tex
1 %%
2 %%
3
4 %\author{Landon Fuller}
5 %\title{Bacula TLS Additions}
6
7 \section{TLS}
8 \label{_Chapter_TLS}
9 \index{TLS}
10 \addcontentsline{toc}{section}{TLS}
11
12 Written by Landon Fuller
13
14 \subsection{Introduction to TLS}
15 \index{TLS Introduction}
16 \index{Introduction!TLS}
17 \addcontentsline{toc}{subsection}{TLS Introduction}
18
19 This patch includes all the back-end code necessary to add complete TLS
20 support to Bacula.  In addition, support for TLS in Console/Director
21 communications has been added as a proof of concept.  Adding support for
22 the remaining daemons will be straight-forward.  Supported features of this
23 patchset include: 
24 \begin{itemize} 
25 \item Client/Server TLS Requirement Negotiation 
26 \item TLSv1 Connections with Server and Client Certificate
27 Validation 
28 \item Forward Secrecy Support via Diffie-Hellman Ephemeral Keying 
29 \end{itemize}
30
31 This document will refer to both ``server'' and ``client'' contexts.  These
32 terms refer to the accepting and initiating peer, respectively.
33
34 Diffie-Hellman anonymous ciphers are not supported by this patchset.  The
35 use of DH anonymous ciphers increases the code complexity and places
36 explicit trust upon the two-way Cram-MD5 implementation.  Cram-MD5 is
37 subject to known plaintext attacks, and is should be considered
38 considerably less secure than PKI certificate-based authentication.
39
40 Appropriate autoconf macros have been added to detect and use OpenSSL. Two
41 additional preprocessor defines have been added: \emph{HAVE\_TLS} and
42 \emph{HAVE\_OPENSSL}.  All changes not specific to OpenSSL rely on
43 \emph{HAVE\_TLS}.  OpenSSL-specific code is constrained to
44 \emph{src/lib/tls.c} to facilitate the support of alternative TLS
45 implementations.
46
47 I have submitted the code in \emph{src/lib/tls.c} under the 3 clause BSD
48 license.  I prefer the stronger warranty disclaimer of an actual license,
49 but I'm also willing to provide access to the code under the public domain.
50
51 \subsection{New Configuration Directives}
52 \index{TLS Configuration Directives}
53 \index{Directives!TLS Configuration}
54 \addcontentsline{toc}{subsection}{New Configuration Directives}
55
56 Additional configuration directives have been added to both the Console and
57 Director resources.  These new directives are defined as follows:
58
59 \begin{itemize}
60 \item \underline{TLS Enable} \emph{(yes/no)}
61 Enable TLS support.
62
63 \item \underline{TLS Require} \emph{(yes/no)}
64 Require TLS connections.
65
66 \item \underline{TLS Certificate} \emph{(path)}
67 Path to PEM encoded TLS certificate.  Used as either a client or server
68 certificate.
69
70 \item \underline{TLS Key} \emph{(path)}
71 Path to PEM encoded TLS private key.  Must correspond with the TLS
72 certificate.
73
74 \item \underline{TLS Verify Peer} \emph{(yes/no)}
75 Verify peer certificate.  Instructs server to request and verify the
76 client's x509 certificate.  Any client certificate signed by a known-CA
77 will be accepted unless the TLS Allowed CN configuration directive is used.
78 Not valid in a client context.
79
80 \item \underline{TLS Allowed CN} \emph{(string list)}
81 Common name attribute of allowed peer certificates.  If directive is
82 specified, all client certificates will be verified against this list.
83 This directive may be specified more than once.  Not valid in a client
84 context.
85
86 \item \underline{TLS CA Certificate File} \emph{(path)}
87 Path to PEM encoded TLS CA certificate(s).  Multiple certificates are
88 permitted in the file.  One of \emph{TLS CA Certificate File} or \emph{TLS
89 CA Certificate Dir} are required in a server context if \underline{TLS
90 Verify Peer} is also specified, and are always required in a client
91 context.
92
93 \item \underline{TLS CA Certificate Dir} \emph{(path)}
94 Path to TLS CA certificate directory.  In the current implementation,
95 certificates must be stored PEM encoded with OpenSSL-compatible hashes.
96 One of \emph{TLS CA Certificate File} or \emph{TLS CA Certificate Dir} are
97 required in a server context if \emph{TLS Verify Peer} is also specified,
98 and are always required in a client context.
99
100 \item \underline{TLS DH File} \emph{(path)}
101 Path to PEM encoded Diffie-Hellman parameter file.  If this directive is
102 specified, DH ephemeral keying will be enabled, allowing for forward
103 secrecy of communications.  This directive is only valid within a server
104 context.  To generate the parameter file, you may use openssl:
105 \footnotesize
106 \begin{verbatim} 
107 openssl dhparam -out dh1024.pem -5 1024 
108 \end{verbatim}
109 \normalsize
110 \end{itemize}
111
112 \subsection{TLS API Implementation}
113 \index{TLS API Implimentation}
114 \index{API Implimentation!TLS}
115 \addcontentsline{toc}{subsection}{TLS API Implementation}
116
117 To facilitate the use of additional TLS libraries, all OpenSSL-specific
118 code has been implemented within \emph{src/lib/tls.c}.  In turn, a generic
119 TLS API is exported.
120
121 \subsubsection{Library Initialization and Cleanup}
122 \index{Library Initialization and Cleanup}
123 \index{Initialization and Cleanup!Library}
124 \addcontentsline{toc}{subsubsection}{Library Initialization and Cleanup}
125
126 \footnotesize
127 \begin{verbatim}
128 int init_tls (void);
129 \end{verbatim}
130 \normalsize
131
132 Performs TLS library initialization, including seeding of the PRNG. PRNG
133 seeding has not yet been implemented for win32.
134
135 \footnotesize
136 \begin{verbatim}
137 int cleanup_tls (void);
138 \end{verbatim}
139 \normalsize
140
141 Performs TLS library cleanup.
142
143 \subsubsection{Manipulating TLS Contexts}
144 \index{TLS Context Manipulation}
145 \index{Contexts!Manipulating TLS}
146 \addcontentsline{toc}{subsubsection}{Manipulating TLS Contexts}
147
148 \footnotesize
149 \begin{verbatim}
150 TLS_CONTEXT  *new_tls_context (const char *ca_certfile,
151         const char *ca_certdir, const char *certfile,
152         const char *keyfile, const char *dhfile, bool verify_peer);
153 \end{verbatim}
154 \normalsize
155
156 Allocates and initalizes a new opaque \emph{TLS\_CONTEXT} structure.  The
157 \emph{TLS\_CONTEXT} structure maintains default TLS settings from which
158 \emph{TLS\_CONNECTION} structures are instantiated.  In the future the
159 \emph{TLS\_CONTEXT} structure may be used to maintain the TLS session
160 cache.  \emph{ca\_certfile} and \emph{ca\_certdir} arguments are used to
161 initialize the CA verification stores.  The \emph{certfile} and
162 \emph{keyfile} arguments are used to initialize the local certificate and
163 private key.  If \emph{dhfile} is non-NULL, it is used to initialize
164 Diffie-Hellman ephemeral keying.  If \emph{verify\_peer} is \emph{true} ,
165 client certificate validation is enabled.
166
167 \footnotesize
168 \begin{verbatim}
169 void free_tls_context (TLS_CONTEXT *ctx);
170 \end{verbatim}
171 \normalsize
172
173 Deallocated a previously allocated \emph{TLS\_CONTEXT} structure.
174
175 \subsubsection{Performing Post-Connection Verification}
176 \index{TLS Post-Connection Verification}
177 \index{Verification!TLS Post-Connection}
178 \addcontentsline{toc}{subsubsection}{Performing Post-Connection Verification}
179
180 \footnotesize
181 \begin{verbatim}
182 bool tls_postconnect_verify_host (TLS_CONNECTION *tls, const char *host);
183 \end{verbatim}
184 \normalsize
185
186 Performs post-connection verification of the peer-supplied x509
187 certificate.  Checks whether the \emph{subjectAltName} and
188 \emph{commonName} attributes match the supplied \emph{host} string.
189 Returns \emph{true} if there is a match, \emph{false} otherwise.
190
191 \footnotesize
192 \begin{verbatim}
193 bool tls_postconnect_verify_cn (TLS_CONNECTION *tls, alist *verify_list);
194 \end{verbatim}
195 \normalsize
196
197 Performs post-connection verification of the peer-supplied x509
198 certificate.  Checks whether the \emph{commonName} attribute matches any
199 strings supplied via the \emph{verify\_list} parameter.  Returns
200 \emph{true} if there is a match, \emph{false} otherwise.
201
202 \subsubsection{Manipulating TLS Connections}
203 \index{TLS Connection Manipulation}
204 \index{Connections!Manipulating TLS}
205 \addcontentsline{toc}{subsubsection}{Manipulating TLS Connections}
206
207 \footnotesize
208 \begin{verbatim}
209 TLS_CONNECTION *new_tls_connection (TLS_CONTEXT *ctx, int fd);
210 \end{verbatim}
211 \normalsize
212
213 Allocates and initializes a new \emph{TLS\_CONNECTION} structure with
214 context \emph{ctx} and file descriptor \emph{fd}.
215
216 \footnotesize
217 \begin{verbatim}
218 void free_tls_connection (TLS_CONNECTION *tls);
219 \end{verbatim}
220 \normalsize
221
222 Deallocates memory associated with the \emph{tls} structure.
223
224 \footnotesize
225 \begin{verbatim}
226 bool tls_bsock_connect (BSOCK *bsock);
227 \end{verbatim}
228 \normalsize
229
230 Negotiates a a TLS client connection via \emph{bsock}.  Returns \emph{true}
231 if successful, \emph{false} otherwise.  Will fail if there is a TLS
232 protocol error or an invalid certificate is presented
233
234 \footnotesize
235 \begin{verbatim}
236 bool tls_bsock_accept (BSOCK *bsock);
237 \end{verbatim}
238 \normalsize
239
240 Accepts a TLS client connection via \emph{bsock}.  Returns \emph{true} if
241 successful, \emph{false} otherwise.  Will fail if there is a TLS protocol
242 error or an invalid certificate is presented.
243
244 \footnotesize
245 \begin{verbatim}
246 bool tls_bsock_shutdown (BSOCK *bsock);
247 \end{verbatim}
248 \normalsize
249
250 Issues a blocking TLS shutdown request to the peer via \emph{bsock}. This function may not wait for the peer's reply.
251
252 \footnotesize
253 \begin{verbatim}
254 int tls_bsock_writen (BSOCK *bsock, char *ptr, int32_t nbytes);
255 \end{verbatim}
256 \normalsize
257
258 Writes \emph{nbytes} from \emph{ptr} via the \emph{TLS\_CONNECTION}
259 associated with \emph{bsock}.  Due to OpenSSL's handling of \emph{EINTR},
260 \emph{bsock} is set non-blocking at the start of the function, and restored
261 to its original blocking state before the function returns.  Less than
262 \emph{nbytes} may be written if an error occurs.  The actual number of
263 bytes written will be returned.
264
265 \footnotesize
266 \begin{verbatim}
267 int tls_bsock_readn (BSOCK *bsock, char *ptr, int32_t nbytes);
268 \end{verbatim}
269 \normalsize
270
271 Reads \emph{nbytes} from the \emph{TLS\_CONNECTION} associated with
272 \emph{bsock} and stores the result in \emph{ptr}.  Due to OpenSSL's
273 handling of \emph{EINTR}, \emph{bsock} is set non-blocking at the start of
274 the function, and restored to its original blocking state before the
275 function returns.  Less than \emph{nbytes} may be read if an error occurs.
276 The actual number of bytes read will be returned.
277
278 \subsection{Bnet API Changes}
279 \index{Bnet API Changes}
280 \index{API Changes!Bnet}
281 \addcontentsline{toc}{subsection}{Bnet API Changes}
282
283 A minimal number of changes were required in the Bnet socket API. The BSOCK
284 structure was expanded to include an associated TLS\_CONNECTION structure,
285 as well as a flag to designate the current blocking state of the socket.
286 The blocking state flag is required for win32, where it does not appear
287 possible to discern the current blocking state of a socket.
288
289 \subsubsection{Negotiating a TLS Connection}
290 \index{Negotiating a TLS Connection}
291 \index{TLS Connection!Negotiating}
292 \addcontentsline{toc}{subsubsection}{Negotiating a TLS Connection}
293
294 \emph{bnet\_tls\_server()} and \emph{bnet\_tls\_client()} were both
295 implemented using the new TLS API as follows:
296
297 \footnotesize
298 \begin{verbatim}
299 int bnet_tls_client(TLS_CONTEXT *ctx, BSOCK * bsock);
300 \end{verbatim}
301 \normalsize
302
303 Negotiates a TLS session via \emph{bsock} using the settings from
304 \emph{ctx}.  Returns 1 if successful, 0 otherwise.
305
306 \footnotesize
307 \begin{verbatim}
308 int bnet_tls_server(TLS_CONTEXT *ctx, BSOCK * bsock, alist *verify_list);
309 \end{verbatim}
310 \normalsize
311
312 Accepts a TLS client session via \emph{bsock} using the settings from
313 \emph{ctx}.  If \emph{verify\_list} is non-NULL, it is passed to
314 \emph{tls\_postconnect\_verify\_cn()} for client certificate verification.
315
316 \subsubsection{Manipulating Socket Blocking State}
317 \index{Manipulating Socket Blocking State}
318 \index{Socket Blocking State!Manipulating}
319 \index{Blocking State!Socket!Manipulating}
320 \addcontentsline{toc}{subsubsection}{Manipulating Socket Blocking State}
321
322 Three functions were added for manipulating the blocking state of a socket
323 on both Win32 and Unix-like systems.  The Win32 code was written according
324 to the MSDN documentation, but has not been tested.
325
326 These functions are prototyped as follows:
327
328 \footnotesize
329 \begin{verbatim}
330 int bnet_set_nonblocking (BSOCK *bsock);
331 \end{verbatim}
332 \normalsize
333
334 Enables non-blocking I/O on the socket associated with \emph{bsock}.
335 Returns a copy of the socket flags prior to modification.
336
337 \footnotesize
338 \begin{verbatim}
339 int bnet_set_blocking (BSOCK *bsock);
340 \end{verbatim}
341 \normalsize
342
343 Enables blocking I/O on the socket associated with \emph{bsock}.  Returns a
344 copy of the socket flags prior to modification.
345
346 \footnotesize
347 \begin{verbatim}
348 void bnet_restore_blocking (BSOCK *bsock, int flags);
349 \end{verbatim}
350 \normalsize
351
352 Restores blocking or non-blocking IO setting on the socket associated with
353 \emph{bsock}.  The \emph{flags} argument must be the return value of either
354 \emph{bnet\_set\_blocking()} or \emph{bnet\_restore\_blocking()}.
355
356 \pagebreak
357
358 \subsection{Authentication Negotiation}
359 \index{Authentication Negotiation}
360 \index{Negotiation!TLS Authentication}
361 \addcontentsline{toc}{subsection}{Authentication Negotiation}
362
363 Backwards compatibility with the existing SSL negotiation hooks implemented
364 in src/lib/cram-md5.c have been maintained.  The
365 \emph{cram\_md5\_get\_auth()} function has been modified to accept an
366 integer pointer argument, tls\_remote\_need.  The TLS requirement
367 advertised by the remote host is returned via this pointer.
368
369 After exchanging cram-md5 authentication and TLS requirements, both the
370 client and server independently decide whether to continue:
371
372 \footnotesize
373 \begin{verbatim}
374 if (!cram_md5_get_auth(dir, password, &tls_remote_need) ||
375         !cram_md5_auth(dir, password, tls_local_need)) {
376 [snip]
377 /* Verify that the remote host is willing to meet our TLS requirements */
378 if (tls_remote_need < tls_local_need && tls_local_need != BNET_TLS_OK &&
379         tls_remote_need != BNET_TLS_OK) {
380    sendit(_("Authorization problem:"
381             " Remote server did not advertise required TLS support.\n"));
382    auth_success = false;
383    goto auth_done;
384 }
385
386 /* Verify that we are willing to meet the remote host's requirements */
387 if (tls_remote_need > tls_local_need && tls_local_need != BNET_TLS_OK &&
388         tls_remote_need != BNET_TLS_OK) {
389    sendit(_("Authorization problem:"
390             " Remote server requires TLS.\n"));
391    auth_success = false;
392    goto auth_done;
393 }
394 \end{verbatim}
395 \normalsize