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