libtls/config.rs
1// Copyright (c) 2019 Reyk Floeter <contact@reykfloeter.com>
2//
3// Permission to use, copy, modify, and distribute this software for any
4// purpose with or without fee is hereby granted, provided that the above
5// copyright notice and this permission notice appear in all copies.
6//
7// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
10// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
13// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14//
15// The documentation is based on libtls man pages of the LibreSSL project,
16// provided under the same ISC-style license (see https://www.libressl.org/):
17//
18// Copyright (c) 2015, 2016 Bob Beck <beck@openbsd.org>
19// Copyright (c) 2016 Brent Cook <bcook@openbsd.org>
20// Copyright (c) 2017 Claudio Jeker <claudio@openbsd.org>
21// Copyright (c) 2015 Doug Hogan <doug@openbsd.org>
22// Copyright (c) 2017 Ingo Schwarze <schwarze@openbsd.org>
23// Copyright (c) 2014, 2015, 2016, 2017, 2018 Joel Sing <jsing@openbsd.org>
24// Copyright (c) 2015 Reyk Floeter <reyk@openbsd.org>
25// Copyright (c) 2014, 2015 Ted Unangst <tedu@openbsd.org>
26//
27// Permission to use, copy, modify, and distribute this software for any
28// purpose with or without fee is hereby granted, provided that the above
29// copyright notice and this permission notice appear in all copies.
30//
31// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
32// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
33// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
34// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
35// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
36// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
37// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
38
39//! [`Tls`] clients and servers are configured with the [`Config`]
40//! configuration context and its helper funtions.
41//!
42//! # Example
43//!
44//! ```
45//! use libtls::{config::{self, Config}, error};
46//!
47//! fn tls_server_config() -> error::Result<Config> {
48//! let mut tls_config = Config::new()?;
49//!
50//! let valid_cert = include_bytes!("../tests/eccert.crt");
51//! let valid_key = include_bytes!("../tests/eccert.key");
52//!
53//! // Sets the key pair and wipes the private key file from memory afterwards
54//! let res = tls_config.set_keypair_mem(valid_cert, valid_key);
55//! config::unload_file(valid_key.to_vec());
56//! res?;
57//!
58//! // The following examples are all set by default and it is not
59//! // not required to set them.
60//! tls_config.set_ciphers("secure")?;
61//! tls_config.set_protocols(libtls::TLS_PROTOCOLS_DEFAULT)?;
62//! tls_config.prefer_ciphers_server();
63//! tls_config.verify();
64//!
65//! Ok(tls_config)
66//! }
67//! # let tls_config = tls_server_config().unwrap();
68//! ```
69//!
70//! [`Tls`]: ../tls/struct.Tls.html
71//! [`Config`]: struct.Config.html
72
73use crate::{error, tls::Tls, util::*};
74use std::{
75 collections::HashMap,
76 convert::TryInto,
77 ffi::{CStr, CString},
78 io,
79 marker::{Send, Sync},
80 os::unix::io::RawFd,
81 path::{Path, PathBuf},
82};
83
84/// The TLS configuration context for [`Tls`] connections.
85///
86/// Before a [`Tls`] connection is created, a configuration must be created.
87/// Several methods exist to change the options of the configuration; see
88/// [`set_protocols`], [`ocsp_require_stapling`], [`verify`].
89///
90/// [`Tls`]: ../tls/struct.Tls.html
91/// [`ocsp_require_stapling`]: #method.ocsp_require_stapling
92/// [`set_protocols`]: #method.set_protocols
93/// [`tls_config_load_file`]: ../fn.tls_config_load_file.html
94/// [`verify`]: #method.verify
95#[derive(Debug)]
96pub struct Config(pub(crate) *mut libtls_sys::tls_config);
97
98/// The TLS configuration context for [`Tls`] connections.
99#[deprecated(since = "1.1.1", note = "Please use `Config` instead of `TlsConfig`")]
100pub type TlsConfig = Config;
101
102impl Config {
103 /// Create a new configuration.
104 ///
105 /// The `new` function allocates, initializes, and returns a new default
106 /// configuration object that can be used for future [`Tls`] connections.
107 ///
108 /// # Errors
109 ///
110 /// Returns an [`io::Error`] on error or an out of memory condition.
111 ///
112 /// # Example
113 ///
114 /// ```
115 /// # use libtls::{config::Config, error::Result};
116 /// # fn tls_config() -> Result<()> {
117 /// let config = Config::new()?;
118 /// # Ok(())
119 /// # }
120 /// # tls_config().unwrap();
121 /// ```
122 ///
123 /// # See also
124 ///
125 /// [`tls_config_new(3)`](https://man.openbsd.org/tls_config_new.3)
126 ///
127 /// [`Tls`]: ../tls/struct.Tls.html
128 /// [`io::Error`]: https://doc.rust-lang.org/std/io/struct.Error.html
129 pub fn new() -> io::Result<Self> {
130 let config = unsafe { libtls_sys::tls_config_new() };
131 if config.is_null() {
132 Err(io::Error::last_os_error())
133 } else {
134 Ok(Config(config))
135 }
136 }
137
138 /// Wrap a raw C `tls_config` object.
139 ///
140 /// # Safety
141 ///
142 /// This function assumes that the raw pointer is valid, and takes
143 /// ownership of the libtls object.
144 /// Do not call `tls_free` yourself, since the `drop` destructor will
145 /// take care of it.
146 ///
147 /// # Panics
148 ///
149 /// Panics if `config` is a null pointer.
150 pub unsafe fn from_sys(config: *mut libtls_sys::tls_config) -> Self {
151 if config.is_null() {
152 panic!(io::Error::last_os_error())
153 }
154 Config(config)
155 }
156
157 /// Add additional files of a public and private key pair.
158 ///
159 /// The `add_keypair_file` method adds an additional public certificate, and
160 /// private key from the specified files, used as an alternative certificate
161 /// for Server Name Indication (server only).
162 ///
163 /// # Example
164 ///
165 /// ```
166 /// # use libtls::{config::Config, error::Result};
167 /// # fn tls_config() -> Result<()> {
168 /// let mut config = Config::new()?;
169 /// assert!(config.add_keypair_file("does_not_exist.crt", "does_not_exist.key").is_err());
170 /// # Ok(())
171 /// # }
172 /// # tls_config().unwrap();
173 /// ```
174 ///
175 /// # See also
176 ///
177 /// [`tls_config_add_keypair_file(3)`](https://man.openbsd.org/tls_config_add_keypair_file.3)
178 pub fn add_keypair_file<P: AsRef<Path>>(
179 &mut self,
180 cert_file: P,
181 key_file: P,
182 ) -> error::Result<()> {
183 call_file2(
184 self,
185 (cert_file, "cert file"),
186 (key_file, "key file"),
187 libtls_sys::tls_config_add_keypair_file,
188 )
189 }
190
191 /// Add an additional public and private key pair from memory.
192 ///
193 /// The `add_keypair_mem` method adds an additional public certificate, and
194 /// private key from memory, used as an alternative certificate for Server
195 /// Name Indication (server only).
196 ///
197 /// # Example
198 ///
199 /// ```
200 /// # use libtls::{config::Config, error::Result};
201 /// # fn tls_config() -> Result<()> {
202 /// let mut config = Config::new()?;
203 /// let valid_cert = include_bytes!("../tests/eccert.crt");
204 /// let valid_key = include_bytes!("../tests/eccert.key");
205 /// config.add_keypair_mem(valid_cert, valid_key)?;
206 /// # Ok(())
207 /// # }
208 /// # tls_config().unwrap();
209 /// ```
210 ///
211 /// # See also
212 ///
213 /// [`tls_config_add_keypair_mem(3)`](https://man.openbsd.org/tls_config_add_keypair_mem.3)
214 pub fn add_keypair_mem(&mut self, cert: &[u8], key: &[u8]) -> error::Result<()> {
215 cvt(self, unsafe {
216 libtls_sys::tls_config_add_keypair_mem(
217 self.0,
218 cert.as_ptr(),
219 cert.len().try_into()?,
220 key.as_ptr(),
221 key.len().try_into()?,
222 )
223 })
224 }
225
226 /// Add additional files of a public and private key pair and an OCSP staple.
227 ///
228 /// The `add_keypair_ocsp_file` method adds an additional public certificate,
229 /// private key, and DER-encoded OCSP staple from the specified files, used
230 /// as an alternative certificate for Server Name Indication (server only).
231 ///
232 /// # See also
233 ///
234 /// [`add_keypair_file`](#method.add_keypair_file),
235 /// [`tls_config_add_keypair_ocsp_file(3)`](https://man.openbsd.org/tls_config_add_keypair_ocsp_file.3)
236 pub fn add_keypair_ocsp_file<P: AsRef<Path>>(
237 &mut self,
238 cert_file: P,
239 key_file: P,
240 ocsp_staple_file: P,
241 ) -> error::Result<()> {
242 call_file3(
243 self,
244 (cert_file, "cert file"),
245 (key_file, "key file"),
246 (ocsp_staple_file, "ocsp staple file"),
247 libtls_sys::tls_config_add_keypair_ocsp_file,
248 )
249 }
250
251 /// Add an additional public and private key pair and OCSP staple from memory.
252 ///
253 /// The `add_keypair_ocsp_mem` method adds an additional public certificate,
254 /// private key, and DER-encoded OCSP staple from memory, used as an
255 /// alternative certificate for Server Name Indication (server only).
256 ///
257 /// # See also
258 ///
259 /// [`add_keypair_mem`](#method.add_keypair_mem),
260 /// [`tls_config_add_keypair_ocsp_mem(3)`](https://man.openbsd.org/tls_config_add_keypair_ocsp_mem.3)
261 pub fn add_keypair_ocsp_mem(
262 &mut self,
263 cert: &[u8],
264 key: &[u8],
265 ocsp_staple: &[u8],
266 ) -> error::Result<()> {
267 cvt(self, unsafe {
268 libtls_sys::tls_config_add_keypair_ocsp_mem(
269 self.0,
270 cert.as_ptr(),
271 cert.len().try_into()?,
272 key.as_ptr(),
273 key.len().try_into()?,
274 ocsp_staple.as_ptr(),
275 ocsp_staple.len().try_into()?,
276 )
277 })
278 }
279
280 /// Set the ALPN protocols that are supported.
281 ///
282 /// The `set_alpn` method sets the ALPN protocols that are supported. The
283 /// alpn string is a comma separated list of protocols, in order of
284 /// preference.
285 ///
286 /// # Example
287 ///
288 /// ```
289 /// # use libtls::{config::Config, error::Result};
290 /// # fn tls_config() -> Result<()> {
291 /// let mut config = Config::new()?;
292 ///
293 /// // The `h2` ALPN is used by HTTP/2:
294 /// config.set_alpn("h2")?;
295 /// # Ok(())
296 /// # }
297 /// # tls_config().unwrap();
298 /// ```
299 ///
300 /// # See also
301 ///
302 /// [`tls_config_set_alpn(3)`](https://man.openbsd.org/tls_config_set_alpn.3)
303 pub fn set_alpn(&mut self, alpn: &str) -> error::Result<()> {
304 call_string1(self, alpn, libtls_sys::tls_config_set_alpn)
305 }
306
307 /// Set the CA file.
308 ///
309 /// The `set_ca_file` method sets the filename used to load a file containing
310 /// the root certificates. The default filename can be returned with the
311 /// [`default_ca_cert_file`] function.
312 ///
313 /// # See also
314 ///
315 /// [`add_keypair_file`](#method.add_keypair_file.html),
316 /// [`tls_config_set_ca_file(3)`](https://man.openbsd.org/tls_config_set_ca_file.3)
317 ///
318 /// [`default_ca_cert_file`]: fn.default_ca_cert_file.html
319 pub fn set_ca_file<P: AsRef<Path>>(&mut self, ca_file: P) -> error::Result<()> {
320 call_file1(
321 self,
322 (ca_file, "ca file"),
323 libtls_sys::tls_config_set_ca_file,
324 )
325 }
326
327 /// Set the path that should be searched for the CA files.
328 ///
329 /// The `set_ca_path` method sets sets the path (directory) which should be
330 /// searched for root certificates.
331 ///
332 /// # See also
333 ///
334 /// [`set_ca_file`](#method.set_ca_file.html),
335 /// [`tls_config_set_ca_path(3)`](https://man.openbsd.org/tls_config_set_ca_path.3)
336 pub fn set_ca_path<P: AsRef<Path>>(&mut self, ca_path: P) -> error::Result<()> {
337 call_file1(
338 self,
339 (ca_path, "ca path"),
340 libtls_sys::tls_config_set_ca_path,
341 )
342 }
343
344 /// Set the CA from memory.
345 ///
346 /// The `set_ca_mem` method directly sets the root certificates directly from memory.
347 ///
348 ///
349 /// # See also
350 ///
351 /// [`add_keypair_mem`](#method.add_keypair_mem),
352 /// [`tls_config_set_ca_mem(3)`](https://man.openbsd.org/tls_config_set_ca_mem.3)
353 pub fn set_ca_mem(&mut self, ca: &[u8]) -> error::Result<()> {
354 cvt(self, unsafe {
355 libtls_sys::tls_config_set_ca_mem(self.0, ca.as_ptr(), ca.len().try_into()?)
356 })
357 }
358
359 /// Set the CA file from memory.
360 ///
361 /// The `set_ca_mem` method sets the root certificates directly from memory.
362 ///
363 /// # See also
364 ///
365 /// [`add_keypair_mem`](#method.add_keypair_mem.html),
366 /// [`tls_config_set_ca_mem(3)`](https://man.openbsd.org/tls_config_set_ca_mem.3)
367 pub fn tls_config_set_ca_mem(&mut self, ca: &[u8]) -> error::Result<()> {
368 cvt(self, unsafe {
369 libtls_sys::tls_config_set_ca_mem(self.0, ca.as_ptr(), ca.len().try_into()?)
370 })
371 }
372
373 /// Set the public certificate file.
374 ///
375 /// The `set_cert_file` method sets file from which the public certificate
376 /// will be read.
377 ///
378 /// # See also
379 ///
380 /// [`add_keypair_file`](#method.add_keypair_file),
381 /// [`tls_config_set_cert_file(3)`](https://man.openbsd.org/tls_config_set_cert_file.3)
382 pub fn set_cert_file<P: AsRef<Path>>(&mut self, cert_file: P) -> error::Result<()> {
383 call_file1(
384 self,
385 (cert_file, "cert file"),
386 libtls_sys::tls_config_set_cert_file,
387 )
388 }
389
390 /// Set the public certificate from memory.
391 ///
392 /// The `set_cert_mem` method sets the public certificate directly from
393 /// memory.
394 ///
395 /// # See also
396 ///
397 /// [`add_keypair_mem`](#method.add_keypair_mem),
398 /// [`tls_config_set_cert_mem(3)`](https://man.openbsd.org/tls_config_set_cert_mem.3)
399 pub fn set_cert_mem(&mut self, cert: &[u8]) -> error::Result<()> {
400 cvt(self, unsafe {
401 libtls_sys::tls_config_set_cert_mem(self.0, cert.as_ptr(), cert.len().try_into()?)
402 })
403 }
404
405 /// Set the list of cipher that may be used.
406 ///
407 /// The `set_ciphers` method sets the list of ciphers that may be used.
408 /// Lists of ciphers are specified by name, and the permitted names are:
409 ///
410 /// * `secure` (or alias `default`)
411 /// * `compat`
412 /// * `legacy`
413 /// * `insecure` (or alias `all`)
414 ///
415 /// Alternatively, libssl cipher strings can be specified. See the CIPHERS
416 /// section of [`openssl(1)`] for further information.
417 ///
418 /// # Example
419 ///
420 /// ```
421 /// # use libtls::{config::Config, error::Result};
422 /// # fn tls_config() -> Result<()> {
423 /// let mut config = Config::new()?;
424 ///
425 /// // Only use `compat` if you run into problems with the `secure` default!
426 /// config.set_ciphers("compat")?;
427 /// # Ok(())
428 /// # }
429 /// # tls_config().unwrap();
430 /// ```
431 ///
432 /// # See also
433 ///
434 /// [`openssl(1)`],
435 /// [`tls_config_set_ciphers(3)`](https://man.openbsd.org/tls_config_set_ciphers.3)
436 ///
437 /// [`openssl(1)`]: http://man.openbsd.org/openssl.1#CIPHERS
438 pub fn set_ciphers(&mut self, ciphers: &str) -> error::Result<()> {
439 call_string1(self, ciphers, libtls_sys::tls_config_set_ciphers)
440 }
441
442 /// Set the CRL file.
443 ///
444 /// The `set_crl_file` method sets the filename used to load a file
445 /// containing the Certificate Revocation List (CRL).
446 ///
447 /// # See also
448 ///
449 /// [`add_keypair_file`](#method.add_keypair_file.html),
450 /// [`tls_config_set_crl_file(3)`](https://man.openbsd.org/tls_config_set_crl_file.3)
451 pub fn set_crl_file<P: AsRef<Path>>(&mut self, crl_file: P) -> error::Result<()> {
452 call_file1(
453 self,
454 (crl_file, "crl file"),
455 libtls_sys::tls_config_set_crl_file,
456 )
457 }
458
459 /// Set the CRL from memory.
460 ///
461 /// The `set_crl_mem` method sets the Certificate Revocation List (CRL)
462 /// directly from memory.
463 ///
464 /// # See also
465 ///
466 /// [`add_keypair_mem`](#method.add_keypair_mem.html),
467 /// [`tls_config_set_crl_mem(3)`](https://man.openbsd.org/tls_config_set_crl_mem.3)
468 pub fn set_crl_mem(&mut self, crl: &[u8]) -> error::Result<()> {
469 cvt(self, unsafe {
470 libtls_sys::tls_config_set_crl_mem(self.0, crl.as_ptr(), crl.len().try_into()?)
471 })
472 }
473
474 /// Set the parameters of an Diffie-Hellman Ephemeral (DHE) key exchange.
475 ///
476 /// The `set_dheparams` method specifies the parameters that will be used
477 /// during Diffie-Hellman Ephemeral (DHE) key exchange. Possible values are
478 /// `none`, `auto` and `legacy`. In `auto` mode, the key size for the
479 /// ephemeral key is automatically selected based on the size of the private
480 /// key being used for signing. In `legacy` mode, 1024 bit ephemeral keys
481 /// are used. The default value is `none`, which disables DHE key exchange.
482 ///
483 /// # Example
484 ///
485 /// ```
486 /// # use libtls::{config::Config, error::Result};
487 /// # fn tls_config() -> Result<()> {
488 /// let mut config = Config::new()?;
489 /// config.set_dheparams("auto")?;
490 /// # Ok(())
491 /// # }
492 /// # tls_config().unwrap();
493 /// ```
494 ///
495 /// # See also
496 ///
497 /// [`tls_config_set_dheparams(3)`](https://man.openbsd.org/tls_config_set_dheparams.3)
498 pub fn set_dheparams(&mut self, dheparams: &str) -> error::Result<()> {
499 call_string1(self, dheparams, libtls_sys::tls_config_set_dheparams)
500 }
501
502 /// The `set_ecdhecurve` method was replaced by [set_ecdhecurves](#method.set_ecdhecurves).
503 #[deprecated(
504 since = "2.6.1-LibreSSL",
505 note = "Replaced by [set_ecdhecurves](#method.set_ecdhecurves)."
506 )]
507 pub fn set_ecdhecurve(&mut self, ecdhecurve: &str) -> error::Result<()> {
508 call_string1(self, ecdhecurve, libtls_sys::tls_config_set_ecdhecurve)
509 }
510
511 /// Set the curves of an Elliptic Curve Diffie-Hellman Ephemeral (ECDHE) key exchange.
512 ///
513 /// The `set_ecdhecurves` method specifies the names of the elliptic curves
514 /// that may be used during Elliptic Curve Diffie-Hellman Ephemeral (ECDHE)
515 /// key exchange. This is a comma separated list, given in order of
516 /// preference. The special value of "default" will use the default curves
517 /// (currently X25519, P-256 and P-384). This function replaces
518 /// [`set_ecdhecurve`], which is deprecated.
519 ///
520 /// # Example
521 ///
522 /// ```
523 /// # use libtls::{config::Config, error::Result};
524 /// # fn tls_config() -> Result<()> {
525 /// let mut config = Config::new()?;
526 /// config.set_ecdhecurves("X25519,P-384")?;
527 /// # Ok(())
528 /// # }
529 /// # tls_config().unwrap();
530 /// ```
531 ///
532 /// # See also
533 ///
534 /// [`tls_config_set_ecdhecurves(3)`](https://man.openbsd.org/tls_config_set_ecdhecurves.3)
535 ///
536 /// [`set_ecdhecurve`]: #method.set_ecdhecurve
537 pub fn set_ecdhecurves(&mut self, ecdhecurves: &str) -> error::Result<()> {
538 call_string1(self, ecdhecurves, libtls_sys::tls_config_set_ecdhecurves)
539 }
540
541 /// Set the private key file.
542 ///
543 /// The `set_key_file` method sets the file from which the private key will
544 /// be read.
545 ///
546 /// # See also
547 ///
548 /// [`add_keypair_file`](#method.add_keypair_file),
549 /// [`tls_config_set_key_file(3)`](https://man.openbsd.org/tls_config_set_key_file.3)
550 pub fn set_key_file<P: AsRef<Path>>(&mut self, key_file: P) -> error::Result<()> {
551 call_file1(
552 self,
553 (key_file, "key file"),
554 libtls_sys::tls_config_set_key_file,
555 )
556 }
557
558 /// Set the private key from memory.
559 ///
560 /// The `set_key_mem` method directly sets the private key from memory.
561 ///
562 /// # See also
563 ///
564 /// [`add_keypair_mem`](#method.add_keypair_mem),
565 /// [`tls_config_set_key_mem(3)`](https://man.openbsd.org/tls_config_set_key_mem.3)
566 pub fn set_key_mem(&mut self, key: &[u8]) -> error::Result<()> {
567 cvt(self, unsafe {
568 libtls_sys::tls_config_set_key_mem(self.0, key.as_ptr(), key.len().try_into()?)
569 })
570 }
571
572 /// Set the files of the public and private key pair.
573 ///
574 /// The `set_keypair_file` method sets the files from which the public
575 /// certificate, and private key will be read.
576 ///
577 /// # See also
578 ///
579 /// [`add_keypair_file`](#method.add_keypair_file),
580 /// [`tls_config_set_keypair_file(3)`](https://man.openbsd.org/tls_config_set_keypair_file.3)
581 pub fn set_keypair_file<P: AsRef<Path>>(
582 &mut self,
583 cert_file: P,
584 key_file: P,
585 ) -> error::Result<()> {
586 call_file2(
587 self,
588 (cert_file, "cert file"),
589 (key_file, "key file"),
590 libtls_sys::tls_config_set_keypair_file,
591 )
592 }
593
594 /// Set the public and private key pair from memory.
595 ///
596 /// The `set_keypair_mem` method directly sets the public certificate, and
597 /// private key from memory.
598 ///
599 /// # See also
600 ///
601 /// [`add_keypair_mem`](#method.add_keypair_mem),
602 /// [`tls_config_set_keypair_mem(3)`](https://man.openbsd.org/tls_config_set_keypair_mem.3)
603 pub fn set_keypair_mem(&mut self, cert: &[u8], key: &[u8]) -> error::Result<()> {
604 cvt(self, unsafe {
605 libtls_sys::tls_config_set_keypair_mem(
606 self.0,
607 cert.as_ptr(),
608 cert.len().try_into()?,
609 key.as_ptr(),
610 key.len().try_into()?,
611 )
612 })
613 }
614
615 /// Set the files of a public and private key pair and an OCSP staple.
616 ///
617 /// The `set_keypair_ocsp_file` method sets the public certificate,
618 /// private key, and DER-encoded OCSP staple from the specified files.
619 ///
620 /// # See also
621 ///
622 /// [`add_keypair_ocsp_file`](#method.add_keypair_ocsp_file),
623 /// [`tls_config_set_keypair_ocsp_file(3)`](https://man.openbsd.org/tls_config_set_keypair_ocsp_file.3)
624 pub fn set_keypair_ocsp_file<P: AsRef<Path>>(
625 &mut self,
626 cert_file: P,
627 key_file: P,
628 ocsp_staple_file: P,
629 ) -> error::Result<()> {
630 call_file3(
631 self,
632 (cert_file, "cert file"),
633 (key_file, "key file"),
634 (ocsp_staple_file, "ocsp staple file"),
635 libtls_sys::tls_config_set_keypair_ocsp_file,
636 )
637 }
638
639 /// Set the public and private key pair and an OCSP staple from memory.
640 ///
641 /// The `set_keypair_ocsp_mem` method sets the public certificate,
642 /// private key, and DER-encoded OCSP staple directly from memory.
643 ///
644 /// # See also
645 ///
646 /// [`add_keypair_ocsp_mem`](#method.add_keypair_ocsp_mem),
647 /// [`tls_config_set_keypair_ocsp_mem(3)`](https://man.openbsd.org/tls_config_set_keypair_ocsp_mem.3)
648 pub fn set_keypair_ocsp_mem(
649 &mut self,
650 cert: &[u8],
651 key: &[u8],
652 ocsp_staple: &[u8],
653 ) -> error::Result<()> {
654 cvt(self, unsafe {
655 libtls_sys::tls_config_set_keypair_ocsp_mem(
656 self.0,
657 cert.as_ptr(),
658 cert.len().try_into()?,
659 key.as_ptr(),
660 key.len().try_into()?,
661 ocsp_staple.as_ptr(),
662 ocsp_staple.len().try_into()?,
663 )
664 })
665 }
666
667 /// Set the OCSP staple from memory.
668 ///
669 /// The `set_keypair_ocsp_mem` method sets a DER-encoded OCSP response to be
670 /// stapled during the TLS handshake from memory.
671 ///
672 /// # See also
673 ///
674 /// [`add_keypair_mem`](#method.add_keypair_mem),
675 /// [`tls_config_set_ocsp_staple_mem(3)`](https://man.openbsd.org/tls_config_set_ocsp_staple_mem.3)
676 pub fn set_ocsp_staple_mem(&mut self, ocsp_staple: &[u8]) -> error::Result<()> {
677 cvt(self, unsafe {
678 libtls_sys::tls_config_set_ocsp_staple_mem(
679 self.0,
680 ocsp_staple.as_ptr(),
681 ocsp_staple.len().try_into()?,
682 )
683 })
684 }
685
686 /// Set the OCSP staple file.
687 ///
688 /// The `set_keypair_ocsp_mem` method sets a DER-encoded OCSP response to be
689 /// stapled during the TLS handshake from the specified file.
690 ///
691 ///
692 /// # See also
693 ///
694 /// [`add_keypair_file`](#method.add_keypair_file),
695 /// [`tls_config_set_ocsp_staple_file(3)`](https://man.openbsd.org/tls_config_set_ocsp_staple_file.3)
696 pub fn set_ocsp_staple_file<P: AsRef<Path>>(
697 &mut self,
698 ocsp_staple_file: P,
699 ) -> error::Result<()> {
700 call_file1(
701 self,
702 (ocsp_staple_file, "ocsp staple file"),
703 libtls_sys::tls_config_set_ocsp_staple_file,
704 )
705 }
706
707 /// Set which versions of the TLS protocol may be used.
708 ///
709 /// The `set_protocols` method specifies which versions of the TLS protocol
710 /// may be used. Possible values are the bitwise OR of:
711 ///
712 /// * [`TLS_PROTOCOL_TLSv1_0`]
713 /// * [`TLS_PROTOCOL_TLSv1_1`]
714 /// * [`TLS_PROTOCOL_TLSv1_2`]
715 ///
716 /// Only supported with LibreSSL 3.1.0 or later:
717 ///
718 /// * [`TLS_PROTOCOL_TLSv1_3`]
719 ///
720 /// Additionally, the values [`TLS_PROTOCOL_TLSv1`] (TLSv1.0,
721 /// TLSv1.1, TLSv1.2, and TLSv1.3), [`TLS_PROTOCOLS_ALL`] (all
722 /// supported protocols) and [`TLS_PROTOCOLS_DEFAULT`] (TLSv1.2
723 /// and TLSv1.3) may be used. TLSv1.3 is only supported with
724 /// LibreSSL 3.1.0 or later.
725 ///
726 /// # Example
727 ///
728 /// ```
729 /// # use libtls::{config::{self, Config}, error::Result};
730 /// # fn tls_config() -> Result<()> {
731 /// let mut config = Config::new()?;
732 /// let protocols = config::parse_protocols("tlsv1.1,tlsv1.2")?;
733 /// config.set_protocols(protocols)?;
734 /// # Ok(())
735 /// # }
736 /// # tls_config().unwrap();
737 /// ```
738 ///
739 /// # See also
740 ///
741 /// [`parse_protocols`](fn.parse_protocols.html),
742 /// [`tls_config_set_protocols(3)`](https://man.openbsd.org/tls_config_set_protocols.3)
743 ///
744 /// [`TLS_PROTOCOLS_ALL`]: ../constant.TLS_PROTOCOLS_ALL.html
745 /// [`TLS_PROTOCOLS_DEFAULT`]: ../constant.TLS_PROTOCOLS_DEFAULT.html
746 /// [`TLS_PROTOCOL_TLSv1`]: ../constant.TLS_PROTOCOL_TLSv1.html
747 /// [`TLS_PROTOCOL_TLSv1_0`]: ../constant.TLS_PROTOCOL_TLSv1_0.html
748 /// [`TLS_PROTOCOL_TLSv1_1`]: ../constant.TLS_PROTOCOL_TLSv1_1.html
749 /// [`TLS_PROTOCOL_TLSv1_2`]: ../constant.TLS_PROTOCOL_TLSv1_2.html
750 /// [`TLS_PROTOCOL_TLSv1_3`]: ../constant.TLS_PROTOCOL_TLSv1_3.html
751 pub fn set_protocols(&mut self, protocols: u32) -> error::Result<()> {
752 call_arg1(self, protocols, libtls_sys::tls_config_set_protocols)
753 }
754
755 /// Set a file descriptor to manage data for TLS sessions.
756 ///
757 /// The `set_session_fd` method sets a file descriptor to be used to manage
758 /// data for TLS sessions (client only). The given file descriptor must be a
759 /// regular file and be owned by the current user, with permissions being
760 /// restricted to only allow the owner to read and write the file (0600). If
761 /// the file has a non-zero length, the client will attempt to read session
762 /// data from this file and resume the previous TLS session with the server.
763 /// Upon a successful handshake the file will be updated with current session
764 /// data, if available. The caller is responsible for closing this file
765 /// descriptor, after all [`TLS`] contexts that have been configured to use it
766 /// have been [dropped].
767 ///
768 /// # See also
769 ///
770 /// [`tls_config_set_session_fd(3)`](https://man.openbsd.org/tls_config_set_session_fd.3)
771 ///
772 /// [`Tls`]: ../tls/struct.Tls.html
773 /// [dropped]: ../tls/struct.Tls.html#impl-Drop
774 pub fn set_session_fd(&mut self, session_fd: RawFd) -> error::Result<()> {
775 call_arg1(self, session_fd, libtls_sys::tls_config_set_session_fd)
776 }
777
778 /// Set the certificate verification depth.
779 ///
780 /// The `set_verify_depth` method limits the number of intermediate
781 /// certificates that will be followed during certificate validation.
782 ///
783 /// # See also
784 ///
785 /// [`tls_config_set_verify_depth(3)`](https://man.openbsd.org/tls_config_set_verify_depth.3)
786 pub fn set_verify_depth(&mut self, verify_depth: usize) -> error::Result<()> {
787 call_arg1(
788 self,
789 verify_depth as i32,
790 libtls_sys::tls_config_set_verify_depth,
791 )
792 }
793
794 /// Prefer ciphers in the client's cipher list.
795 ///
796 /// The `prefer_ciphers_client` method prefers ciphers in the client's cipher
797 /// list when selecting a cipher suite (server only). This is considered to
798 /// be less secure than preferring the server's list.
799 ///
800 /// # See also
801 ///
802 /// [`tls_config_prefer_ciphers_client(3)`](https://man.openbsd.org/tls_config_prefer_ciphers_client.3)
803 pub fn prefer_ciphers_client(&mut self) {
804 unsafe { libtls_sys::tls_config_prefer_ciphers_client(self.0) }
805 }
806
807 /// Prefer ciphers in the servers's cipher list.
808 ///
809 /// The `prefer_ciphers_server` method prefers ciphers in the server's cipher
810 /// list when selecting a cipher suite (server only). This is considered to
811 /// be more secure than preferring the client's list and is the default.
812 ///
813 /// # See also
814 ///
815 /// [`tls_config_prefer_ciphers_server(3)`](https://man.openbsd.org/tls_config_prefer_ciphers_server.3)
816 pub fn prefer_ciphers_server(&mut self) {
817 unsafe { libtls_sys::tls_config_prefer_ciphers_server(self.0) }
818 }
819
820 /// Disable certificate verification.
821 ///
822 /// The `insecure_noverifycert` method disables certificate verification and
823 /// OCSP validation.
824 ///
825 /// # See also
826 ///
827 /// [`tls_config_insecure_noverifycert(3)`](https://man.openbsd.org/tls_config_insecure_noverifycert.3)
828 pub fn insecure_noverifycert(&mut self) {
829 unsafe { libtls_sys::tls_config_insecure_noverifycert(self.0) }
830 }
831
832 /// Disable server name verification.
833 ///
834 /// The `insecure_noverifyname` method disables server name verification
835 /// (client only).
836 ///
837 /// # See also
838 ///
839 /// [`tls_config_insecure_noverifyname(3)`](https://man.openbsd.org/tls_config_insecure_noverifyname.3)
840 pub fn insecure_noverifyname(&mut self) {
841 unsafe { libtls_sys::tls_config_insecure_noverifyname(self.0) }
842 }
843
844 /// Disable certificate validity checking.
845 ///
846 /// The `insecure_noverifytime` method disables validity checking of
847 /// certificates and OCSP validation.
848 ///
849 /// # See also
850 ///
851 /// [`tls_config_insecure_noverifytime(3)`](https://man.openbsd.org/tls_config_insecure_noverifytime.3)
852 pub fn insecure_noverifytime(&mut self) {
853 unsafe { libtls_sys::tls_config_insecure_noverifytime(self.0) }
854 }
855
856 /// Enable all certificate verification.
857 ///
858 /// The `verify` method reenables server name and certificate verification.
859 ///
860 /// # See also
861 ///
862 /// [`tls_config_verify(3)`](https://man.openbsd.org/tls_config_verify.3)
863 pub fn verify(&mut self) {
864 // reenables OCSP validation as well?
865 unsafe { libtls_sys::tls_config_verify(self.0) }
866 }
867
868 /// Require OCSP stapling.
869 ///
870 /// The `ocsp_require_stapling` method requires that a valid stapled OCSP
871 /// response be provided during the TLS handshake.
872 ///
873 /// # See also
874 ///
875 /// [`tls_config_ocsp_require_stapling(3)`](https://man.openbsd.org/tls_config_ocsp_require_stapling.3)
876 pub fn ocsp_require_stapling(&mut self) {
877 unsafe { libtls_sys::tls_config_ocsp_require_stapling(self.0) }
878 }
879
880 /// Enable client certificate verification.
881 ///
882 /// The `verify_client` method enables client certificate verification,
883 /// requiring the client to send a certificate (server only).
884 ///
885 /// # See also
886 ///
887 /// [`tls_config_verify_client(3)`](https://man.openbsd.org/tls_config_verify_client.3)
888 pub fn verify_client(&mut self) {
889 unsafe { libtls_sys::tls_config_verify_client(self.0) }
890 }
891
892 /// Enable optional client certificate verification.
893 ///
894 /// The `verify_client_optional` method enables client certificate
895 /// verification, without requiring the client to send a certificate (server
896 /// only).
897 ///
898 /// # See also
899 ///
900 /// [`tls_config_verify_client_optional(3)`](https://man.openbsd.org/tls_config_verify_client_optional.3)
901 pub fn verify_client_optional(&mut self) {
902 unsafe { libtls_sys::tls_config_verify_client_optional(self.0) }
903 }
904
905 /// Securely clear secret keys.
906 ///
907 /// The `clear_keys` method clears any secret keys from memory.
908 ///
909 /// # See also
910 ///
911 /// [`tls_config_clear_keys(3)`](https://man.openbsd.org/tls_config_clear_keys.3)
912 pub fn clear_keys(&mut self) {
913 unsafe { libtls_sys::tls_config_clear_keys(self.0) }
914 }
915
916 /// Set the session identifier for TLS sessions.
917 ///
918 /// The `set_session_id` method sets the session identifier that will be used
919 /// by the TLS server when sessions are enabled (server only). By default a
920 /// random value is used.
921 ///
922 /// # Example
923 ///
924 /// ```
925 /// # use libtls::{config::Config, error::Result, *};
926 /// # use rand::{thread_rng, Rng};
927 /// # fn tls_config() -> Result<()> {
928 /// let mut session_id = [0; TLS_MAX_SESSION_ID_LENGTH as usize];
929 /// thread_rng().fill(&mut session_id[..]);
930 ///
931 /// let mut config = Config::new()?;
932 /// config.set_session_id(&session_id[..])?;
933 /// # Ok(())
934 /// # }
935 /// # tls_config().unwrap();
936 /// ```
937 ///
938 /// # See also
939 ///
940 /// [`tls_config_set_session_id(3)`](https://man.openbsd.org/tls_config_set_session_id.3)
941 pub fn set_session_id(&mut self, session_id: &[u8]) -> error::Result<()> {
942 cvt(self, unsafe {
943 libtls_sys::tls_config_set_session_id(
944 self.0,
945 session_id.as_ptr(),
946 session_id.len().try_into()?,
947 )
948 })
949 }
950
951 /// Set the lifetime for TLS sessions.
952 ///
953 /// The `set_session_lifetime` method sets the lifetime to be used for TLS
954 /// sessions (server only). Session support is disabled if a lifetime of
955 /// zero is specified, which is the default.
956 ///
957 /// # See also
958 ///
959 /// [`tls_config_set_session_lifetime(3)`](https://man.openbsd.org/tls_config_set_session_lifetime.3)
960 pub fn set_session_lifetime(&mut self, lifetime: usize) -> error::Result<()> {
961 call_arg1(
962 self,
963 lifetime as i32,
964 libtls_sys::tls_config_set_session_lifetime,
965 )
966 }
967
968 /// Add a key for the encryption and authentication of TLS tickets.
969 ///
970 /// The `add_ticket_key` method adds a key used for the encryption and
971 /// authentication of TLS tickets (server only). By default keys are
972 /// generated and rotated automatically based on their lifetime. This
973 /// function should only be used to synchronise ticket encryption key across
974 /// multiple processes. Re-adding a known key will result in an error,
975 /// unless it is the most recently added key.
976 ///
977 /// # Example
978 ///
979 /// ```
980 /// # use libtls::{config::Config, error::Result, *};
981 /// # use rand::{thread_rng, Rng};
982 /// # fn tls_config() -> Result<()> {
983 /// let mut key = [0; TLS_TICKET_KEY_SIZE as usize];
984 /// thread_rng().fill(&mut key[..]);
985 ///
986 /// let mut config = Config::new()?;
987 /// config.add_ticket_key(1, &mut key[..])?;
988 /// # Ok(())
989 /// # }
990 /// # tls_config().unwrap();
991 /// ```
992 ///
993 /// # See also
994 ///
995 /// [`tls_config_add_ticket_key(3)`](https://man.openbsd.org/tls_config_add_ticket_key.3)
996 pub fn add_ticket_key(&mut self, keyrev: u32, key: &mut [u8]) -> error::Result<()> {
997 // XXX key should be const, consider changing this in the upstream API
998 cvt(self, unsafe {
999 libtls_sys::tls_config_add_ticket_key(
1000 self.0,
1001 keyrev,
1002 key.as_mut_ptr(),
1003 key.len().try_into()?,
1004 )
1005 })
1006 }
1007}
1008
1009impl error::LastError for Config {
1010 /// Returns the configuration last error.
1011 ///
1012 /// The `last_error` method returns an error if no error occurred with config
1013 /// at all, or if memory allocation failed while trying to assemble the
1014 /// string describing the most recent error related to config.
1015 ///
1016 /// # See also
1017 ///
1018 /// [`tls_config_error(3)`](https://man.openbsd.org/tls_config_error.3)
1019 fn last_error(&self) -> error::Result<String> {
1020 unsafe { cvt_no_error(libtls_sys::tls_config_error(self.0)) }
1021 }
1022
1023 fn to_error<T>(errstr: String) -> error::Result<T> {
1024 Err(error::Error::ConfigError(errstr))
1025 }
1026}
1027
1028impl Drop for Config {
1029 /// Free the configuration object. This should only happen when no
1030 /// more [`Tls`] contexts are to be configured.
1031 ///
1032 /// # See also
1033 ///
1034 /// [`tls_config_free(3)`](https://man.openbsd.org/tls_config_free.3)
1035 ///
1036 /// [`Tls`]: ../tls/struct.Tls.html
1037 fn drop(&mut self) {
1038 unsafe { libtls_sys::tls_config_free(self.0) };
1039 }
1040}
1041
1042unsafe impl Send for Config {}
1043unsafe impl Sync for Config {}
1044
1045/// Return path of the default CA file.
1046///
1047/// The `default_ca_cert_file` utility function returns the path of the file that
1048/// contains the default root certificates.
1049///
1050/// # Example
1051///
1052/// ```
1053/// # use libtls::config;
1054/// let certs = config::default_ca_cert_file();
1055/// assert!(certs.is_absolute());
1056/// ```
1057///
1058/// # See also
1059///
1060/// [`tls_default_ca_cert_file(3)`](https://man.openbsd.org/tls_default_ca_cert_file.3)
1061pub fn default_ca_cert_file() -> PathBuf {
1062 unsafe { CStr::from_ptr(libtls_sys::tls_default_ca_cert_file()) }
1063 .to_string_lossy()
1064 .into_owned()
1065 .into()
1066}
1067
1068/// Parse protocol string.
1069///
1070/// The `tls_config_parse_protocols` utility function parses a
1071/// protocol string and returns the corresponding value via the
1072/// protocols argument. This value can then be passed to the
1073/// [`set_protocols`] method. The protocol string is a comma or colon
1074/// separated list of keywords. Valid keywords are `tlsv1.0`,
1075/// `tlsv1.1`, `tlsv1.2`, `tlsv1.3`, `all` (all supported protocols),
1076/// `default` (an alias for secure), `legacy` (an alias for all) and
1077/// `secure` (currently TLSv1.2 and TLSv1.3). If a value has a
1078/// negative prefix (in the form of a leading exclamation mark) then
1079/// it is removed from the list of available protocols, rather than
1080/// being added to it.
1081///
1082/// # Example
1083///
1084/// ```
1085/// # use libtls::{config::Config, error::Result, *};
1086/// # fn tls_config() -> Result<()> {
1087/// // Parse a list of allowed protocols:
1088/// let protocols = config::parse_protocols("tlsv1.1,tlsv1.2").unwrap();
1089/// assert_eq!(protocols, TLS_PROTOCOL_TLSv1_1|TLS_PROTOCOL_TLSv1_2);
1090///
1091/// // The default is to use the `secure` protocols:
1092/// let protocols = config::parse_protocols("default").unwrap();
1093/// assert_eq!(protocols, TLS_PROTOCOLS_DEFAULT);
1094/// assert_ne!(protocols, TLS_PROTOCOLS_ALL);
1095/// # Ok(())
1096/// # }
1097/// # tls_config().unwrap();
1098/// ```
1099///
1100/// # See also
1101///
1102/// [`tls_config_parse_protocols(3)`](https://man.openbsd.org/tls_config_parse_protocols.3)
1103///
1104/// [`set_protocols`]: #method.set_protocols
1105pub fn parse_protocols(protostr: &str) -> error::Result<u32> {
1106 let c_protostr = CString::new(protostr)?;
1107 let mut protocols: u32 = 0;
1108
1109 let retval =
1110 unsafe { libtls_sys::tls_config_parse_protocols(&mut protocols, c_protostr.as_ptr()) };
1111 if retval == -1 {
1112 Err(io::Error::new(io::ErrorKind::Other, "Invalid protocols string").into())
1113 } else {
1114 Ok(protocols)
1115 }
1116}
1117
1118/// Load a certificate or key file.
1119///
1120/// The `load_file` function loads a certificate or key from disk into memory
1121/// to be used with [`set_ca_mem`], [`set_cert_mem`], [`set_crl_mem`] or
1122/// [`set_key_mem`]. A private key will be decrypted if the optional password
1123/// argument is specified.
1124///
1125/// # Example
1126///
1127/// ```
1128/// # use libtls::{config, error::Result};
1129/// # fn tls_config() -> Result<()> {
1130/// # let filename = file!();
1131/// let data = config::load_file(filename, None)?;
1132/// config::unload_file(data);
1133/// # Ok(())
1134/// # }
1135/// # tls_config().unwrap();
1136/// ```
1137///
1138/// # See also
1139///
1140/// [`unload_file`],
1141/// [`tls_load_file(3)`](https://man.openbsd.org/tls_load_file.3)
1142///
1143/// [`set_ca_mem`]: struct.Config.html#method.set_ca_mem
1144/// [`set_cert_mem`]: struct.Config.html#method.set_cert_mem
1145/// [`set_crl_mem`]: struct.Config.html#method.set_crl_mem
1146/// [`set_key_mem`]: struct.Config.html#method.set_key_mem
1147/// [`unload_file`]: fn.unload_file.html
1148pub fn load_file<P: AsRef<Path>>(file: P, password: Option<&str>) -> error::Result<Vec<u8>> {
1149 let mut size = 0;
1150 let s_file = cvt_option(
1151 file.as_ref().to_str(),
1152 io::Error::new(io::ErrorKind::InvalidInput, "file"),
1153 )?;
1154 unsafe {
1155 let c_file = CString::new(s_file)?;
1156 let data = match password {
1157 Some(password) => {
1158 let c_password = CString::new(password)?;
1159
1160 let raw = c_password.into_raw();
1161 let data = libtls_sys::tls_load_file(c_file.as_ptr(), &mut size, raw);
1162
1163 // Make sure that the raw pointer is not leaked
1164 let _ = CString::from_raw(raw);
1165
1166 data
1167 }
1168 None => libtls_sys::tls_load_file(c_file.as_ptr(), &mut size, std::ptr::null_mut()),
1169 };
1170 if data.is_null() {
1171 Err(io::Error::last_os_error().into())
1172 } else {
1173 let len = size.try_into()?;
1174 Ok(Vec::from_raw_parts(data, len, len))
1175 }
1176 }
1177}
1178
1179/// Securely unload file that was loaded into memory.
1180///
1181/// The `unload_file` function unloads the memory that was returned from an
1182/// earlier [`load_file`] call, ensuring that the memory contents is discarded.
1183///
1184/// # See also
1185///
1186/// [`tls_unload_file(3)`](https://man.openbsd.org/tls_unload_file.3)
1187///
1188/// [`load_file`]: fn.load_file.html
1189pub fn unload_file(mut data: Vec<u8>) {
1190 let ptr = data.as_mut_ptr();
1191 let len = data.len() as u64;
1192 std::mem::forget(data);
1193 unsafe { libtls_sys::tls_unload_file(ptr, len) }
1194}
1195
1196#[derive(Debug, Clone)]
1197enum KeyData {
1198 File(PathBuf),
1199 Path(PathBuf),
1200 KeyPairFiles(PathBuf, PathBuf, Option<PathBuf>),
1201 KeyPairMem(Vec<u8>, Vec<u8>, Option<Vec<u8>>),
1202 Mem(Vec<u8>),
1203}
1204
1205/// `Builder` for [`Config`].
1206///
1207/// # Example
1208///
1209/// ```
1210/// # use libtls::{config::Builder, error::Result};
1211/// # use libtls_sys::*;
1212/// # fn tls_config() -> Result<()> {
1213/// # let key = include_bytes!("../tests/eccert.key");
1214/// # let cert = include_bytes!("../tests/eccert.crt");
1215/// # let ticket_key1 = [0; TLS_TICKET_KEY_SIZE as usize];
1216/// # let ticket_key2 = [0; TLS_TICKET_KEY_SIZE as usize];
1217/// let mut config = Builder::new()
1218/// .keypair_mem(cert, key, None)
1219/// .ticket_key(1, &ticket_key1)
1220/// .ticket_key(2, &ticket_key2)
1221/// .protocols(TLS_PROTOCOLS_ALL)
1222/// .ecdhecurves("X25519")
1223/// .alpn("h2")
1224/// .build()?;
1225/// # Ok(())
1226/// # }
1227/// # tls_config().unwrap();
1228/// ```
1229///
1230/// [`Config`]: struct.Config.html
1231#[derive(Default, Debug, Clone)]
1232pub struct Builder {
1233 alpn: Option<String>,
1234 ca: Option<KeyData>,
1235 ciphers: Option<String>,
1236 crl: Option<KeyData>,
1237 dheparams: Option<String>,
1238 ecdhecurves: Option<String>,
1239 keypairs: Vec<KeyData>,
1240 noverifycert: bool,
1241 noverifyname: bool,
1242 noverifytime: bool,
1243 protocols: Option<u32>,
1244 session_fd: Option<RawFd>,
1245 session_id: Option<Vec<u8>>,
1246 session_lifetime: Option<usize>,
1247 ticket_key: HashMap<u32, Vec<u8>>,
1248 verify: bool,
1249 verify_client: bool,
1250 verify_client_optional: bool,
1251 verify_depth: Option<usize>,
1252}
1253
1254/// `TlsConfigBuilder` for [`TlsConfig`].
1255#[deprecated(
1256 since = "1.1.1",
1257 note = "Please use `Builder` instead of `TlsConfigBuilder`"
1258)]
1259pub type TlsConfigBuilder = Builder;
1260
1261impl Builder {
1262 /// Return new `Builder`.
1263 ///
1264 /// # See also
1265 ///
1266 /// [`Config`](struct.Config.html)
1267 pub fn new() -> Self {
1268 Default::default()
1269 }
1270
1271 /// Build new [`Config`] object.
1272 ///
1273 /// # See also
1274 ///
1275 /// [`Config`]
1276 ///
1277 /// [`Config`]: struct.Config.html
1278 pub fn build(&self) -> error::Result<Config> {
1279 let mut config = Config::new()?;
1280
1281 // First add the keypairs and optional OCSP staples.
1282 self.build_keypairs(&mut config)?;
1283
1284 // Now all the other settings
1285 if let Some(ref alpn) = self.alpn {
1286 config.set_alpn(alpn)?;
1287 }
1288 if let Some(ref ca) = self.ca {
1289 match ca {
1290 KeyData::Mem(mem) => config.set_ca_mem(mem)?,
1291 KeyData::File(file) => config.set_ca_file(file)?,
1292 KeyData::Path(path) => config.set_ca_path(path)?,
1293 _ => return Err(error::Error::NoError),
1294 };
1295 } else if !default_ca_cert_file().exists() {
1296 // Try to use the default CA path as a fallback.
1297 config.set_ca_path("/etc/ssl/certs")?;
1298 };
1299 if let Some(ref ciphers) = self.ciphers {
1300 config.set_ciphers(ciphers)?;
1301 }
1302 if let Some(ref crl) = self.crl {
1303 match crl {
1304 KeyData::Mem(mem) => config.set_ca_mem(mem)?,
1305 KeyData::File(file) => config.set_ca_file(file)?,
1306 _ => return Err(error::Error::NoError),
1307 };
1308 }
1309 if let Some(ref dheparams) = self.dheparams {
1310 config.set_dheparams(dheparams)?;
1311 }
1312 if let Some(ref ecdhecurves) = self.ecdhecurves {
1313 config.set_ecdhecurves(ecdhecurves)?;
1314 }
1315 if let Some(protocols) = self.protocols {
1316 config.set_protocols(protocols)?;
1317 }
1318 if let Some(session_fd) = self.session_fd {
1319 config.set_session_fd(session_fd)?;
1320 }
1321 if let Some(ref session_id) = self.session_id {
1322 config.set_session_id(session_id)?;
1323 }
1324 if let Some(session_lifetime) = self.session_lifetime {
1325 config.set_session_lifetime(session_lifetime)?;
1326 }
1327
1328 // Add ticket keys
1329 for (keyrev, key) in self.ticket_key.iter() {
1330 // The tls_ticket_key() API is "broken" as it requires the key
1331 // as mut and not const.
1332 config.add_ticket_key(*keyrev, key.clone().as_mut_slice())?;
1333 }
1334
1335 // Order verify_* calls in a safe priority.
1336 if self.noverifycert {
1337 config.insecure_noverifycert();
1338 }
1339 if self.noverifyname {
1340 config.insecure_noverifyname();
1341 }
1342 if self.noverifytime {
1343 config.insecure_noverifytime();
1344 }
1345 if let Some(verify_depth) = self.verify_depth {
1346 config.set_verify_depth(verify_depth)?;
1347 }
1348 if self.verify_client_optional {
1349 config.verify_client_optional();
1350 }
1351 if self.verify_client {
1352 config.verify_client();
1353 }
1354 if self.verify {
1355 config.verify();
1356 }
1357
1358 Ok(config)
1359 }
1360
1361 fn build_keypairs(&self, config: &mut Config) -> error::Result<()> {
1362 for (i, kp) in self.keypairs.iter().enumerate() {
1363 match kp {
1364 KeyData::KeyPairMem(cert, key, ocsp) => {
1365 if let Some(ocsp) = ocsp {
1366 // Set the first keypair as the default.
1367 if i == 0 {
1368 config.set_keypair_ocsp_mem(cert, key, ocsp)?;
1369 }
1370 config.add_keypair_ocsp_mem(cert, key, ocsp)?;
1371 } else {
1372 if i == 0 {
1373 config.set_keypair_mem(cert, key)?;
1374 }
1375 config.add_keypair_mem(cert, key)?;
1376 }
1377 }
1378 KeyData::KeyPairFiles(cert, key, ocsp) => {
1379 if let Some(ocsp) = ocsp {
1380 if i == 0 {
1381 config.set_keypair_ocsp_file(cert, key, ocsp)?;
1382 }
1383 config.add_keypair_ocsp_file(cert, key, ocsp)?;
1384 } else {
1385 if i == 0 {
1386 config.set_keypair_file(cert, key)?;
1387 }
1388 config.add_keypair_file(cert, key)?;
1389 }
1390 }
1391 _ => return Err(error::Error::NoError),
1392 };
1393 }
1394
1395 Ok(())
1396 }
1397
1398 /// Build new [`Config`] object and return a configured [`Tls`] client.
1399 ///
1400 /// # See also
1401 ///
1402 /// [`Tls`],
1403 /// [`Config`]
1404 ///
1405 /// [`Tls`]: ../tls/struct.Tls.html
1406 /// [`Config`]: struct.Config.html
1407 pub fn client(&self) -> error::Result<Tls> {
1408 let mut client = Tls::client()?;
1409 client.configure(&self.build()?)?;
1410 Ok(client)
1411 }
1412
1413 /// Build new [`Config`] object and return a configured [`Tls`] server.
1414 ///
1415 /// # See also
1416 ///
1417 /// [`Tls`],
1418 /// [`Config`]
1419 ///
1420 /// [`Tls`]: ../tls/struct.Tls.html
1421 /// [`Config`]: struct.Config.html
1422 pub fn server(&self) -> error::Result<Tls> {
1423 let mut server = Tls::server()?;
1424 server.configure(&self.build()?)?;
1425 Ok(server)
1426 }
1427
1428 /// Set the ALPN protocols that are supported.
1429 ///
1430 /// # See also
1431 ///
1432 /// [`Config::set_alpn`](struct.Config.html#method.set_alpn)
1433 pub fn alpn(&'_ mut self, alpn: &str) -> &'_ mut Self {
1434 self.alpn = Some(alpn.to_owned());
1435 self
1436 }
1437
1438 /// Set the CA file.
1439 ///
1440 /// # See also
1441 ///
1442 /// [`Config::set_ca_file`](struct.Config.html#method.set_ca_file)
1443 pub fn ca_file<P: AsRef<Path>>(&'_ mut self, path: P) -> &'_ mut Self {
1444 self.ca = Some(KeyData::File(path.as_ref().to_owned()));
1445 self
1446 }
1447
1448 /// Set the CA path.
1449 ///
1450 /// # See also
1451 ///
1452 /// [`Config::set_ca_path`](struct.Config.html#method.set_ca_path)
1453 pub fn ca_path<P: AsRef<Path>>(&'_ mut self, path: P) -> &'_ mut Self {
1454 self.ca = Some(KeyData::Path(path.as_ref().to_owned()));
1455 self
1456 }
1457
1458 /// Set the CA from memory.
1459 ///
1460 /// # See also
1461 ///
1462 /// [`Config::set_ca_mem`](struct.Config.html#method.set_ca_mem)
1463 pub fn ca_mem(&'_ mut self, mem: &[u8]) -> &'_ mut Self {
1464 self.ca = Some(KeyData::Mem(mem.to_vec()));
1465 self
1466 }
1467
1468 /// Set the list of cipher that may be used.
1469 ///
1470 /// # See also
1471 ///
1472 /// [`Config::set_ciphers`](struct.Config.html#method.set_ciphers)
1473 pub fn ciphers(&'_ mut self, ciphers: &str) -> &'_ mut Self {
1474 self.ciphers = Some(ciphers.to_owned());
1475 self
1476 }
1477
1478 /// Set the CRL file.
1479 ///
1480 /// # See also
1481 ///
1482 /// [`Config::set_crl_file`](struct.Config.html#method.set_crl_file)
1483 pub fn crl_file<P: AsRef<Path>>(&'_ mut self, path: P) -> &'_ mut Self {
1484 self.crl = Some(KeyData::File(path.as_ref().to_owned()));
1485 self
1486 }
1487
1488 /// Set the CRL from memory.
1489 ///
1490 /// # See also
1491 ///
1492 /// [`Config::set_crl_mem`](struct.Config.html#method.set_crl_mem)
1493 pub fn crl_mem(&'_ mut self, mem: &[u8]) -> &'_ mut Self {
1494 self.crl = Some(KeyData::Mem(mem.to_vec()));
1495 self
1496 }
1497
1498 /// Set the parameters of an Diffie-Hellman Ephemeral (DHE) key exchange.
1499 ///
1500 /// # See also
1501 ///
1502 /// [`Config::set_dheparams`](struct.Config.html#method.set_dheparams)
1503 pub fn dheparams(&'_ mut self, dheparams: &str) -> &'_ mut Self {
1504 self.dheparams = Some(dheparams.to_owned());
1505 self
1506 }
1507
1508 /// Set the curves of an Elliptic Curve Diffie-Hellman Ephemeral (ECDHE) key exchange.
1509 ///
1510 /// # See also
1511 ///
1512 /// [`Config::set_ecdhecurves`](struct.Config.html#method.set_ecdhecurves)
1513 pub fn ecdhecurves(&'_ mut self, ecdhecurves: &str) -> &'_ mut Self {
1514 self.ecdhecurves = Some(ecdhecurves.to_owned());
1515 self
1516 }
1517
1518 /// Add additional files of a public and private key pair and OCSP staple.
1519 ///
1520 /// # See also
1521 ///
1522 /// [`Config::add_keypair_file`](struct.Config.html#method.add_keypair_ocsp_file),
1523 /// [`Config::set_keypair_file`](struct.Config.html#method.set_keypair_ocsp_file)
1524 pub fn keypair_file<P: AsRef<Path>>(
1525 &'_ mut self,
1526 cert: P,
1527 key: P,
1528 ocsp_staple: Option<P>,
1529 ) -> &'_ mut Self {
1530 let certdata = cert.as_ref().to_owned();
1531 let keydata = key.as_ref().to_owned();
1532 let ocspdata = match ocsp_staple {
1533 Some(path) => Some(path.as_ref().to_owned()),
1534 None => None,
1535 };
1536 self.keypairs
1537 .push(KeyData::KeyPairFiles(certdata, keydata, ocspdata));
1538 self
1539 }
1540
1541 /// Add an additional public and private key pair and OCSP staple from memory.
1542 ///
1543 /// # See also
1544 ///
1545 /// [`Config::set_keypair_mem`](struct.Config.html#method.add_keypair_ocsp_mem),
1546 /// [`Config::set_keypair_mem`](struct.Config.html#method.set_keypair_ocsp_mem)
1547 pub fn keypair_mem(
1548 &'_ mut self,
1549 cert: &[u8],
1550 key: &[u8],
1551 ocsp_staple: Option<&[u8]>,
1552 ) -> &'_ mut Self {
1553 let certdata = cert.to_vec();
1554 let keydata = key.to_vec();
1555 let ocspdata = match ocsp_staple {
1556 Some(mem) => Some(mem.to_vec()),
1557 None => None,
1558 };
1559 self.keypairs
1560 .push(KeyData::KeyPairMem(certdata, keydata, ocspdata));
1561 self
1562 }
1563
1564 /// Disable certificate verification.
1565 ///
1566 /// # See also
1567 ///
1568 /// [`Config::insecure_noverifycert`](struct.Config.html#method.insecure_noverifycert)
1569 pub fn noverifycert(&'_ mut self) -> &'_ mut Self {
1570 self.noverifycert = true;
1571 self
1572 }
1573
1574 /// Disable server name verification.
1575 ///
1576 /// # See also
1577 ///
1578 /// [`Config::insecure_noverifyname`](struct.Config.html#method.insecure_noverifyname)
1579 pub fn noverifyname(&'_ mut self) -> &'_ mut Self {
1580 self.noverifyname = true;
1581 self
1582 }
1583
1584 /// Disable certificate validity checking.
1585 ///
1586 /// # See also
1587 ///
1588 /// [`Config::insecure_noverifytime`](struct.Config.html#method.insecure_noverifytime)
1589 pub fn noverifytime(&'_ mut self) -> &'_ mut Self {
1590 self.noverifytime = true;
1591 self
1592 }
1593
1594 /// Set which versions of the TLS protocol may be used.
1595 ///
1596 /// # See also
1597 ///
1598 /// [`Config::set_protocols`](struct.Config.html#method.set_protocols)
1599 pub fn protocols(&'_ mut self, protocols: u32) -> &'_ mut Self {
1600 self.protocols = Some(protocols);
1601 self
1602 }
1603
1604 /// Set a file descriptor to manage data for TLS sessions.
1605 ///
1606 /// # See also
1607 ///
1608 /// [`Config::set_session_fd`](struct.Config.html#method.set_session_fd)
1609 pub fn session_fd(&'_ mut self, fd: RawFd) -> &'_ mut Self {
1610 self.session_fd = Some(fd);
1611 self
1612 }
1613
1614 /// Set the session identifier for TLS sessions.
1615 ///
1616 /// # See also
1617 ///
1618 /// [`Config::set_session_id`](struct.Config.html#method.set_session_id)
1619 pub fn session_id(&'_ mut self, id: &[u8]) -> &'_ mut Self {
1620 self.session_id = Some(id.to_vec());
1621 self
1622 }
1623
1624 /// Set the lifetime for TLS sessions.
1625 ///
1626 /// # See also
1627 ///
1628 /// [`Config::set_session_lifetime`](struct.Config.html#method.set_session_lifetime)
1629 pub fn session_lifetime(&'_ mut self, lifetime: usize) -> &'_ mut Self {
1630 self.session_lifetime = Some(lifetime);
1631 self
1632 }
1633
1634 /// # See also
1635 ///
1636 /// [`Config::add_ticket_key`](struct.Config.html#method.add_ticket_key)
1637 pub fn ticket_key(&'_ mut self, keyrev: u32, key: &[u8]) -> &'_ mut Self {
1638 self.ticket_key.insert(keyrev, key.to_vec());
1639 self
1640 }
1641
1642 /// Enable all certificate verification.
1643 ///
1644 /// # See also
1645 ///
1646 /// [`Config::verify`](struct.Config.html#method.verify)
1647 pub fn verify(&'_ mut self) -> &'_ mut Self {
1648 self.verify = true;
1649 self
1650 }
1651
1652 /// Enable client certificate verification.
1653 ///
1654 /// # See also
1655 ///
1656 /// [`Config::verify_client`](struct.Config.html#method.verify_client)
1657 pub fn verify_client(&'_ mut self) -> &'_ mut Self {
1658 self.verify_client = true;
1659 self
1660 }
1661
1662 /// Enable optional client certificate verification.
1663 ///
1664 /// # See also
1665 ///
1666 /// [`Config::verify_client_optional`](struct.Config.html#method.verify_client_optional)
1667 pub fn verify_client_optional(&'_ mut self) -> &'_ mut Self {
1668 self.verify_client_optional = true;
1669 self
1670 }
1671
1672 /// Set the certificate verification depth.
1673 ///
1674 /// # See also
1675 ///
1676 /// [`Config::verify_depth`](struct.Config.html#method.verify_depth)
1677 pub fn verify_depth(&'_ mut self, depth: usize) -> &'_ mut Self {
1678 self.verify_depth = Some(depth);
1679 self
1680 }
1681}