Skip to main content

compio_py_dynamic_openssl/
sys.rs

1// SPDX-License-Identifier: Apache-2.0 OR MulanPSL-2.0
2// Copyright 2026 Fantix King
3
4use std::ffi::{c_char, c_int, c_long, c_ulong, c_void};
5
6use crate::loader::OpenSSL;
7
8pub const ERR_TXT_MALLOCED: c_int = 0x01;
9pub const ERR_TXT_STRING: c_int = 0x02;
10pub const ERR_LIB_SYS: c_int = 2;
11
12pub const BIO_TYPE_NONE: c_int = 0;
13
14pub const BIO_CTRL_FLUSH: c_int = 11;
15pub const BIO_CTRL_DGRAM_QUERY_MTU: c_int = 40;
16
17pub const BIO_FLAGS_READ: c_int = 0x01;
18pub const BIO_FLAGS_WRITE: c_int = 0x02;
19pub const BIO_FLAGS_IO_SPECIAL: c_int = 0x04;
20pub const BIO_FLAGS_RWS: c_int = BIO_FLAGS_READ | BIO_FLAGS_WRITE | BIO_FLAGS_IO_SPECIAL;
21pub const BIO_FLAGS_SHOULD_RETRY: c_int = 0x08;
22
23pub const SSL_ERROR_SSL: c_int = 1;
24pub const SSL_ERROR_SYSCALL: c_int = 5;
25pub const SSL_ERROR_WANT_READ: c_int = 2;
26pub const SSL_ERROR_WANT_WRITE: c_int = 3;
27pub const SSL_ERROR_ZERO_RETURN: c_int = 6;
28pub const SSL_ERROR_WANT_CLIENT_HELLO_CB: c_int = 11;
29
30pub const SSL_CTRL_SET_TLSEXT_HOSTNAME: c_int = 55;
31
32#[allow(bad_style)]
33pub const TLSEXT_NAMETYPE_host_name: c_int = 0;
34
35#[allow(bad_style)]
36pub enum BIO_METHOD {}
37
38pub enum BIO {}
39
40#[allow(bad_style)]
41pub enum SSL_CTX {}
42
43pub enum SSL {}
44
45#[allow(bad_style)]
46pub enum X509_VERIFY_PARAM {}
47
48#[allow(bad_style)]
49impl OpenSSL {
50    pub unsafe fn BIO_set_retry_read(&self, b: *mut BIO) {
51        unsafe { (self.BIO_set_flags)(b, BIO_FLAGS_READ | BIO_FLAGS_SHOULD_RETRY) }
52    }
53
54    pub unsafe fn BIO_set_retry_write(&self, b: *mut BIO) {
55        unsafe { (self.BIO_set_flags)(b, BIO_FLAGS_WRITE | BIO_FLAGS_SHOULD_RETRY) }
56    }
57
58    pub unsafe fn BIO_clear_retry_flags(&self, b: *mut BIO) {
59        unsafe { (self.BIO_clear_flags)(b, BIO_FLAGS_RWS | BIO_FLAGS_SHOULD_RETRY) }
60    }
61
62    pub unsafe fn SSL_set_tlsext_host_name(&self, s: *mut SSL, name: *mut c_char) -> c_long {
63        unsafe {
64            (self.SSL_ctrl)(
65                s,
66                SSL_CTRL_SET_TLSEXT_HOSTNAME,
67                TLSEXT_NAMETYPE_host_name as c_long,
68                name as *mut c_void,
69            )
70        }
71    }
72
73    pub unsafe fn ERR_get_error_all(
74        &self,
75        file: *mut *const c_char,
76        line: *mut c_int,
77        func: *mut *const c_char,
78        data: *mut *const c_char,
79        flags: *mut c_int,
80    ) -> c_ulong {
81        if self.version_num < 0x30000000 {
82            unsafe {
83                let code = self
84                    .ERR_get_error_line_data
85                    .expect("OpenSSL 1.x should have ERR_get_error_line_data")(
86                    file, line, data, flags,
87                );
88                *func = self
89                    .ERR_func_error_string
90                    .expect("OpenSSL 1.x should have ERR_func_error_string")(
91                    code
92                );
93                code
94            }
95        } else {
96            unsafe {
97                self.ERR_get_error_all
98                    .expect("OpenSSL 3.0 should have ERR_get_error_all")(
99                    file, line, func, data, flags,
100                )
101            }
102        }
103    }
104
105    pub const fn ERR_SYSTEM_ERROR(&self, errcode: c_ulong) -> bool {
106        assert!(self.version_num >= 0x30000000);
107        const ERR_SYSTEM_FLAG: c_ulong = c_int::MAX as c_ulong + 1;
108        errcode & ERR_SYSTEM_FLAG != 0
109    }
110
111    pub const fn ERR_GET_LIB(&self, errcode: c_ulong) -> c_int {
112        if self.version_num < 0x30000000 {
113            ((errcode >> 24) & 0x0FF) as c_int
114        } else {
115            const ERR_LIB_OFFSET: c_ulong = 23;
116            const ERR_LIB_MASK: c_ulong = 0xff;
117            ((ERR_LIB_SYS as c_ulong * (self.ERR_SYSTEM_ERROR(errcode) as c_ulong))
118                | (((errcode >> ERR_LIB_OFFSET) & ERR_LIB_MASK)
119                    * (!self.ERR_SYSTEM_ERROR(errcode) as c_ulong))) as c_int
120        }
121    }
122
123    pub const fn ERR_GET_FUNC(&self, errcode: c_ulong) -> c_int {
124        if self.version_num < 0x30000000 {
125            ((errcode >> 12) & 0xFFF) as c_int
126        } else {
127            0
128        }
129    }
130
131    pub const fn ERR_GET_REASON(&self, errcode: c_ulong) -> c_int {
132        if self.version_num < 0x30000000 {
133            (errcode & 0xFFF) as c_int
134        } else {
135            const ERR_REASON_MASK: c_ulong = 0x7FFFFF;
136            ((ERR_LIB_SYS as c_ulong * (self.ERR_SYSTEM_ERROR(errcode) as c_ulong))
137                | ((errcode & ERR_REASON_MASK) * (!self.ERR_SYSTEM_ERROR(errcode) as c_ulong)))
138                as c_int
139        }
140    }
141}