1use crate::bio::Bio;
30use crate::error::ErrorStack;
31use crate::pkey::{HasPrivate, Pkey};
32use crate::x509::X509;
33use native_ossl_sys as sys;
34use std::ffi::CStr;
35
36#[derive(Debug, Clone, Copy, PartialEq, Eq)]
42pub enum TlsVersion {
43 Tls12 = 0x0303,
45 Tls13 = 0x0304,
47}
48
49#[derive(Debug, Clone, Copy, PartialEq, Eq)]
55pub struct SslVerifyMode(i32);
56
57impl SslVerifyMode {
58 pub const NONE: Self = SslVerifyMode(0x00);
60 pub const PEER: Self = SslVerifyMode(0x01);
62 pub const FAIL_IF_NO_PEER_CERT: Self = SslVerifyMode(0x02);
64
65 #[must_use]
67 pub fn or(self, other: Self) -> Self {
68 SslVerifyMode(self.0 | other.0)
69 }
70}
71
72#[derive(Debug)]
80pub enum SslIoError {
81 WantRead,
83 WantWrite,
85 ZeroReturn,
87 Syscall(ErrorStack),
89 Ssl(ErrorStack),
91 Other(i32),
93}
94
95impl std::fmt::Display for SslIoError {
96 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
97 match self {
98 Self::WantRead => write!(f, "SSL want read"),
99 Self::WantWrite => write!(f, "SSL want write"),
100 Self::ZeroReturn => write!(f, "SSL zero return (peer closed)"),
101 Self::Syscall(e) => write!(f, "SSL syscall error: {e}"),
102 Self::Ssl(e) => write!(f, "SSL error: {e}"),
103 Self::Other(code) => write!(f, "SSL error code {code}"),
104 }
105 }
106}
107
108impl std::error::Error for SslIoError {}
109
110#[derive(Debug, Clone, Copy, PartialEq, Eq)]
114pub enum ShutdownResult {
115 Sent,
117 Complete,
119}
120
121pub struct SslSession {
128 ptr: *mut sys::SSL_SESSION,
129}
130
131unsafe impl Send for SslSession {}
133unsafe impl Sync for SslSession {}
134
135impl Clone for SslSession {
136 fn clone(&self) -> Self {
137 unsafe { sys::SSL_SESSION_up_ref(self.ptr) };
138 SslSession { ptr: self.ptr }
139 }
140}
141
142impl Drop for SslSession {
143 fn drop(&mut self) {
144 unsafe { sys::SSL_SESSION_free(self.ptr) };
145 }
146}
147
148pub struct SslCtx {
157 ptr: *mut sys::SSL_CTX,
158}
159
160unsafe impl Send for SslCtx {}
162unsafe impl Sync for SslCtx {}
163
164impl Clone for SslCtx {
165 fn clone(&self) -> Self {
166 unsafe { sys::SSL_CTX_up_ref(self.ptr) };
167 SslCtx { ptr: self.ptr }
168 }
169}
170
171impl Drop for SslCtx {
172 fn drop(&mut self) {
173 unsafe { sys::SSL_CTX_free(self.ptr) };
174 }
175}
176
177impl SslCtx {
178 pub fn new() -> Result<Self, ErrorStack> {
187 let method = unsafe { sys::TLS_method() };
188 let ptr = unsafe { sys::SSL_CTX_new(method) };
189 if ptr.is_null() {
190 return Err(ErrorStack::drain());
191 }
192 Ok(SslCtx { ptr })
193 }
194
195 pub fn new_client() -> Result<Self, ErrorStack> {
199 let method = unsafe { sys::TLS_client_method() };
200 let ptr = unsafe { sys::SSL_CTX_new(method) };
201 if ptr.is_null() {
202 return Err(ErrorStack::drain());
203 }
204 Ok(SslCtx { ptr })
205 }
206
207 pub fn new_server() -> Result<Self, ErrorStack> {
211 let method = unsafe { sys::TLS_server_method() };
212 let ptr = unsafe { sys::SSL_CTX_new(method) };
213 if ptr.is_null() {
214 return Err(ErrorStack::drain());
215 }
216 Ok(SslCtx { ptr })
217 }
218
219 pub fn set_min_proto_version(&self, ver: TlsVersion) -> Result<(), ErrorStack> {
225 let rc = unsafe { sys::SSL_CTX_ctrl(self.ptr, 123, ver as i64, std::ptr::null_mut()) };
226 if rc != 1 {
227 return Err(ErrorStack::drain());
228 }
229 Ok(())
230 }
231
232 pub fn set_max_proto_version(&self, ver: TlsVersion) -> Result<(), ErrorStack> {
238 let rc = unsafe { sys::SSL_CTX_ctrl(self.ptr, 124, ver as i64, std::ptr::null_mut()) };
239 if rc != 1 {
240 return Err(ErrorStack::drain());
241 }
242 Ok(())
243 }
244
245 pub fn set_verify(&self, mode: SslVerifyMode) {
249 unsafe { sys::SSL_CTX_set_verify(self.ptr, mode.0, None) };
250 }
251
252 pub fn set_cipher_list(&self, list: &CStr) -> Result<(), ErrorStack> {
258 let rc = unsafe { sys::SSL_CTX_set_cipher_list(self.ptr, list.as_ptr()) };
259 if rc != 1 {
260 return Err(ErrorStack::drain());
261 }
262 Ok(())
263 }
264
265 pub fn set_ciphersuites(&self, list: &CStr) -> Result<(), ErrorStack> {
271 let rc = unsafe { sys::SSL_CTX_set_ciphersuites(self.ptr, list.as_ptr()) };
272 if rc != 1 {
273 return Err(ErrorStack::drain());
274 }
275 Ok(())
276 }
277
278 pub fn use_certificate(&self, cert: &X509) -> Result<(), ErrorStack> {
284 let rc = unsafe { sys::SSL_CTX_use_certificate(self.ptr, cert.as_ptr()) };
285 if rc != 1 {
286 return Err(ErrorStack::drain());
287 }
288 Ok(())
289 }
290
291 pub fn use_private_key<T: HasPrivate>(&self, key: &Pkey<T>) -> Result<(), ErrorStack> {
297 let rc = unsafe { sys::SSL_CTX_use_PrivateKey(self.ptr, key.as_ptr()) };
298 if rc != 1 {
299 return Err(ErrorStack::drain());
300 }
301 Ok(())
302 }
303
304 pub fn check_private_key(&self) -> Result<(), ErrorStack> {
310 let rc = unsafe { sys::SSL_CTX_check_private_key(self.ptr) };
311 if rc != 1 {
312 return Err(ErrorStack::drain());
313 }
314 Ok(())
315 }
316
317 pub fn set_default_verify_paths(&self) -> Result<(), ErrorStack> {
321 let rc = unsafe { sys::SSL_CTX_set_default_verify_paths(self.ptr) };
322 if rc != 1 {
323 return Err(ErrorStack::drain());
324 }
325 Ok(())
326 }
327
328 pub fn disable_session_cache(&self) {
330 unsafe { sys::SSL_CTX_ctrl(self.ptr, 44, 0, std::ptr::null_mut()) };
332 }
333
334 pub fn new_ssl(&self) -> Result<Ssl, ErrorStack> {
340 let ptr = unsafe { sys::SSL_new(self.ptr) };
341 if ptr.is_null() {
342 return Err(ErrorStack::drain());
343 }
344 Ok(Ssl { ptr })
345 }
346}
347
348pub struct Ssl {
355 ptr: *mut sys::SSL,
356}
357
358unsafe impl Send for Ssl {}
361
362impl Drop for Ssl {
363 fn drop(&mut self) {
364 unsafe { sys::SSL_free(self.ptr) };
365 }
366}
367
368impl Ssl {
369 pub fn set_bio_duplex(&mut self, bio: Bio) {
377 let ptr = bio.as_ptr();
378 std::mem::forget(bio);
380 unsafe { sys::SSL_set_bio(self.ptr, ptr, ptr) };
383 }
384
385 pub fn set_bio(&mut self, rbio: Bio, wbio: Bio) {
389 let rbio_ptr = rbio.as_ptr();
390 let wbio_ptr = wbio.as_ptr();
391 std::mem::forget(rbio);
393 std::mem::forget(wbio);
394 unsafe { sys::SSL_set_bio(self.ptr, rbio_ptr, wbio_ptr) };
395 }
396
397 pub fn set_hostname(&mut self, hostname: &CStr) -> Result<(), ErrorStack> {
409 let rc = unsafe {
410 sys::SSL_ctrl(
411 self.ptr,
412 55, 0, hostname.as_ptr() as *mut std::os::raw::c_void,
416 )
417 };
418 if rc != 1 {
419 return Err(ErrorStack::drain());
420 }
421 Ok(())
422 }
423
424 pub fn set_connect_state(&mut self) {
429 unsafe { sys::SSL_set_connect_state(self.ptr) };
430 }
431
432 pub fn set_accept_state(&mut self) {
434 unsafe { sys::SSL_set_accept_state(self.ptr) };
435 }
436
437 pub fn connect(&mut self) -> Result<(), SslIoError> {
444 let rc = unsafe { sys::SSL_connect(self.ptr) };
445 if rc == 1 {
446 return Ok(());
447 }
448 Err(self.ssl_io_error(rc))
449 }
450
451 pub fn accept(&mut self) -> Result<(), SslIoError> {
458 let rc = unsafe { sys::SSL_accept(self.ptr) };
459 if rc == 1 {
460 return Ok(());
461 }
462 Err(self.ssl_io_error(rc))
463 }
464
465 pub fn do_handshake(&mut self) -> Result<(), SslIoError> {
472 let rc = unsafe { sys::SSL_do_handshake(self.ptr) };
473 if rc == 1 {
474 return Ok(());
475 }
476 Err(self.ssl_io_error(rc))
477 }
478
479 pub fn read(&mut self, buf: &mut [u8]) -> Result<usize, SslIoError> {
485 let mut readbytes: usize = 0;
486 let rc = unsafe {
487 sys::SSL_read_ex(
488 self.ptr,
489 buf.as_mut_ptr().cast(),
490 buf.len(),
491 std::ptr::addr_of_mut!(readbytes),
492 )
493 };
494 if rc == 1 {
495 return Ok(readbytes);
496 }
497 Err(self.ssl_io_error(rc))
498 }
499
500 pub fn write(&mut self, buf: &[u8]) -> Result<usize, SslIoError> {
506 let mut written: usize = 0;
507 let rc = unsafe {
508 sys::SSL_write_ex(
509 self.ptr,
510 buf.as_ptr().cast(),
511 buf.len(),
512 std::ptr::addr_of_mut!(written),
513 )
514 };
515 if rc == 1 {
516 return Ok(written);
517 }
518 Err(self.ssl_io_error(rc))
519 }
520
521 pub fn shutdown(&mut self) -> Result<ShutdownResult, ErrorStack> {
531 let rc = unsafe { sys::SSL_shutdown(self.ptr) };
532 match rc {
533 1 => Ok(ShutdownResult::Complete),
534 0 => Ok(ShutdownResult::Sent),
535 _ => Err(ErrorStack::drain()),
536 }
537 }
538
539 #[must_use]
544 pub fn peer_certificate(&self) -> Option<X509> {
545 let ptr = unsafe { sys::SSL_get0_peer_certificate(self.ptr) };
546 if ptr.is_null() {
547 return None;
548 }
549 unsafe { sys::X509_up_ref(ptr) };
551 Some(unsafe { X509::from_ptr(ptr) })
552 }
553
554 #[must_use]
559 pub fn get1_session(&self) -> Option<SslSession> {
560 let ptr = unsafe { sys::SSL_get1_session(self.ptr) };
561 if ptr.is_null() {
562 None
563 } else {
564 Some(SslSession { ptr })
565 }
566 }
567
568 pub fn set_session(&mut self, session: &SslSession) -> Result<(), ErrorStack> {
574 let rc = unsafe { sys::SSL_set_session(self.ptr, session.ptr) };
575 if rc != 1 {
576 return Err(ErrorStack::drain());
577 }
578 Ok(())
579 }
580
581 fn ssl_io_error(&self, ret: i32) -> SslIoError {
583 let err = unsafe { sys::SSL_get_error(self.ptr, ret) };
584 match err {
585 2 => SslIoError::WantRead,
586 3 => SslIoError::WantWrite,
587 5 => SslIoError::Syscall(ErrorStack::drain()),
588 6 => SslIoError::ZeroReturn,
589 _ => {
590 let stack = ErrorStack::drain();
591 if stack.errors().next().is_none() {
592 SslIoError::Other(err)
593 } else {
594 SslIoError::Ssl(stack)
595 }
596 }
597 }
598 }
599}
600
601#[cfg(test)]
604mod tests {
605 use super::*;
606 use crate::pkey::{KeygenCtx, Pkey, Private, Public};
607 use crate::x509::{X509Builder, X509NameOwned};
608
609 fn make_ed25519_key() -> (Pkey<Private>, Pkey<Public>) {
613 let mut kgen = KeygenCtx::new(c"ED25519").unwrap();
614 let priv_key = kgen.generate().unwrap();
615 let pub_key = Pkey::<Public>::from(priv_key.clone());
616 (priv_key, pub_key)
617 }
618
619 fn make_self_signed_cert(priv_key: &Pkey<Private>, pub_key: &Pkey<Public>) -> X509 {
621 let mut name = X509NameOwned::new().unwrap();
622 name.add_entry_by_txt(c"CN", b"test").unwrap();
623
624 X509Builder::new()
625 .unwrap()
626 .set_version(2)
627 .unwrap()
628 .set_serial_number(1)
629 .unwrap()
630 .set_not_before_offset(0)
631 .unwrap()
632 .set_not_after_offset(86400)
633 .unwrap()
634 .set_subject_name(&name)
635 .unwrap()
636 .set_issuer_name(&name)
637 .unwrap()
638 .set_public_key(pub_key)
639 .unwrap()
640 .sign(priv_key, None)
641 .unwrap()
642 .build()
643 }
644
645 fn do_handshake_pair(mut client: Ssl, mut server: Ssl) -> Result<(Ssl, Ssl), SslIoError> {
652 let mut client_bio: *mut sys::BIO = std::ptr::null_mut();
653 let mut server_bio: *mut sys::BIO = std::ptr::null_mut();
654 let rc = unsafe {
655 sys::BIO_new_bio_pair(
656 std::ptr::addr_of_mut!(client_bio),
657 0,
658 std::ptr::addr_of_mut!(server_bio),
659 0,
660 )
661 };
662 assert_eq!(rc, 1, "BIO_new_bio_pair failed");
663
664 let client_bio_obj = unsafe { Bio::from_ptr_owned(client_bio) };
667 let server_bio_obj = unsafe { Bio::from_ptr_owned(server_bio) };
668 client.set_bio_duplex(client_bio_obj);
669 server.set_bio_duplex(server_bio_obj);
670
671 let mut client_done = false;
673 let mut server_done = false;
674
675 for _ in 0..20 {
676 if !client_done {
677 match client.connect() {
678 Ok(()) => client_done = true,
679 Err(SslIoError::WantRead | SslIoError::WantWrite) => {}
680 Err(e) => return Err(e),
681 }
682 }
683 if !server_done {
684 match server.accept() {
685 Ok(()) => server_done = true,
686 Err(SslIoError::WantRead | SslIoError::WantWrite) => {}
687 Err(e) => return Err(e),
688 }
689 }
690 if client_done && server_done {
691 return Ok((client, server));
692 }
693 }
694 Err(SslIoError::Other(-1))
695 }
696
697 #[test]
700 fn ctx_new_variants() {
701 SslCtx::new().unwrap();
702 SslCtx::new_client().unwrap();
703 SslCtx::new_server().unwrap();
704 }
705
706 #[test]
707 fn ctx_clone() {
708 let ctx = SslCtx::new().unwrap();
709 let _clone = ctx.clone();
710 }
711
712 #[test]
713 fn ctx_proto_version() {
714 let ctx = SslCtx::new().unwrap();
715 ctx.set_min_proto_version(TlsVersion::Tls12).unwrap();
716 ctx.set_max_proto_version(TlsVersion::Tls13).unwrap();
717 }
718
719 #[test]
720 fn ctx_verify_mode() {
721 let ctx = SslCtx::new().unwrap();
722 ctx.set_verify(SslVerifyMode::NONE);
723 ctx.set_verify(SslVerifyMode::PEER);
724 ctx.set_verify(SslVerifyMode::PEER.or(SslVerifyMode::FAIL_IF_NO_PEER_CERT));
725 }
726
727 #[test]
728 fn ctx_cipher_list() {
729 let ctx = SslCtx::new().unwrap();
730 ctx.set_cipher_list(c"HIGH:!aNULL").unwrap();
731 }
732
733 #[test]
736 fn ctx_load_cert_and_key() {
737 let (priv_key, pub_key) = make_ed25519_key();
738 let cert = make_self_signed_cert(&priv_key, &pub_key);
739
740 let ctx = SslCtx::new_server().unwrap();
741 ctx.use_certificate(&cert).unwrap();
742 ctx.use_private_key(&priv_key).unwrap();
743 ctx.check_private_key().unwrap();
744 }
745
746 #[test]
749 fn tls13_handshake_ed25519() {
750 let (priv_key, pub_key) = make_ed25519_key();
751 let cert = make_self_signed_cert(&priv_key, &pub_key);
752
753 let server_ctx = SslCtx::new_server().unwrap();
755 server_ctx.set_min_proto_version(TlsVersion::Tls13).unwrap();
756 server_ctx.set_max_proto_version(TlsVersion::Tls13).unwrap();
757 server_ctx.use_certificate(&cert).unwrap();
758 server_ctx.use_private_key(&priv_key).unwrap();
759 server_ctx.check_private_key().unwrap();
760 server_ctx.disable_session_cache();
761
762 let client_ctx = SslCtx::new_client().unwrap();
764 client_ctx.set_min_proto_version(TlsVersion::Tls13).unwrap();
765 client_ctx.set_max_proto_version(TlsVersion::Tls13).unwrap();
766 client_ctx.set_verify(SslVerifyMode::NONE);
767 client_ctx.disable_session_cache();
768
769 let client_ssl = client_ctx.new_ssl().unwrap();
770 let server_ssl = server_ctx.new_ssl().unwrap();
771
772 let (mut client, mut server) =
773 do_handshake_pair(client_ssl, server_ssl).expect("TLS 1.3 handshake failed");
774
775 let msg = b"hello TLS 1.3";
777 let n = client.write(msg).unwrap();
778 assert_eq!(n, msg.len());
779
780 let mut buf = [0u8; 64];
781 let n = server.read(&mut buf).unwrap();
782 assert_eq!(&buf[..n], msg);
783
784 let reply = b"world";
786 server.write(reply).unwrap();
787 let n = client.read(&mut buf).unwrap();
788 assert_eq!(&buf[..n], reply);
789 }
790
791 #[test]
792 fn tls12_handshake() {
793 let (priv_key, pub_key) = make_ed25519_key();
794 let cert = make_self_signed_cert(&priv_key, &pub_key);
795
796 let server_ctx = SslCtx::new_server().unwrap();
797 server_ctx.set_min_proto_version(TlsVersion::Tls12).unwrap();
798 server_ctx.set_max_proto_version(TlsVersion::Tls12).unwrap();
799 server_ctx.use_certificate(&cert).unwrap();
800 server_ctx.use_private_key(&priv_key).unwrap();
801 server_ctx.check_private_key().unwrap();
802 server_ctx.disable_session_cache();
803
804 let client_ctx = SslCtx::new_client().unwrap();
805 client_ctx.set_min_proto_version(TlsVersion::Tls12).unwrap();
806 client_ctx.set_max_proto_version(TlsVersion::Tls12).unwrap();
807 client_ctx.set_verify(SslVerifyMode::NONE);
808 client_ctx.disable_session_cache();
809
810 let client_ssl = client_ctx.new_ssl().unwrap();
811 let server_ssl = server_ctx.new_ssl().unwrap();
812
813 let (mut client, mut server) =
814 do_handshake_pair(client_ssl, server_ssl).expect("TLS 1.2 handshake failed");
815
816 client.write(b"tls12").unwrap();
818 let mut buf = [0u8; 16];
819 let n = server.read(&mut buf).unwrap();
820 assert_eq!(&buf[..n], b"tls12");
821 }
822
823 #[test]
824 fn peer_certificate_after_handshake() {
825 let (priv_key, pub_key) = make_ed25519_key();
826 let cert = make_self_signed_cert(&priv_key, &pub_key);
827
828 let cert_der = cert.to_der().unwrap();
830
831 let server_ctx = SslCtx::new_server().unwrap();
832 server_ctx.use_certificate(&cert).unwrap();
833 server_ctx.use_private_key(&priv_key).unwrap();
834 server_ctx.disable_session_cache();
835
836 let client_ctx = SslCtx::new_client().unwrap();
838 client_ctx.set_verify(SslVerifyMode::NONE);
839 client_ctx.disable_session_cache();
840
841 let (client, _server) =
842 do_handshake_pair(client_ctx.new_ssl().unwrap(), server_ctx.new_ssl().unwrap())
843 .unwrap();
844
845 let peer_cert = client.peer_certificate().expect("no peer certificate");
847 let peer_der = peer_cert.to_der().unwrap();
848 assert_eq!(peer_der, cert_der, "peer cert DER mismatch");
849 }
850
851 #[test]
852 fn shutdown_sequence() {
853 let (priv_key, pub_key) = make_ed25519_key();
854 let cert = make_self_signed_cert(&priv_key, &pub_key);
855
856 let server_ctx = SslCtx::new_server().unwrap();
857 server_ctx.use_certificate(&cert).unwrap();
858 server_ctx.use_private_key(&priv_key).unwrap();
859 server_ctx.disable_session_cache();
860
861 let client_ctx = SslCtx::new_client().unwrap();
862 client_ctx.set_verify(SslVerifyMode::NONE);
863 client_ctx.disable_session_cache();
864
865 let (mut client, mut server) =
866 do_handshake_pair(client_ctx.new_ssl().unwrap(), server_ctx.new_ssl().unwrap())
867 .unwrap();
868
869 let r = client.shutdown().unwrap();
871 assert_eq!(r, ShutdownResult::Sent);
872
873 let r = server.shutdown().unwrap();
875 assert_eq!(r, ShutdownResult::Sent);
876
877 let r = client.shutdown().unwrap();
879 assert_eq!(r, ShutdownResult::Complete);
880 }
881
882 #[test]
883 fn verify_mode_bits() {
884 let both = SslVerifyMode::PEER.or(SslVerifyMode::FAIL_IF_NO_PEER_CERT);
885 assert_eq!(both.0, 0x03);
886 }
887}