Skip to content

Commit 12c57ce

Browse files
committed
Add ssl.RAND_* functions
1 parent 31905bd commit 12c57ce

File tree

2 files changed

+47
-4
lines changed

2 files changed

+47
-4
lines changed

Lib/ssl.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@
108108
# SSLSyscallError, SSLEOFError,
109109
)
110110
from _ssl import txt2obj as _txt2obj, nid2obj as _nid2obj
111-
# from _ssl import RAND_status, RAND_add, RAND_bytes, RAND_pseudo_bytes
111+
from _ssl import RAND_status, RAND_add, RAND_bytes, RAND_pseudo_bytes
112112
try:
113113
from _ssl import RAND_egd
114114
except ImportError:

vm/src/stdlib/ssl.rs

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use crate::obj::objbytes::PyBytesRef;
77
use crate::obj::objstr::{PyString, PyStringRef};
88
use crate::obj::{objtype::PyClassRef, objweakref::PyWeak};
99
use crate::pyobject::{
10-
IntoPyObject, PyClassImpl, PyObjectRef, PyRef, PyResult, PyValue, TryFromObject,
10+
Either, IntoPyObject, PyClassImpl, PyObjectRef, PyRef, PyResult, PyValue, TryFromObject,
1111
};
1212
use crate::types::create_type;
1313
use crate::VirtualMachine;
@@ -25,7 +25,7 @@ use openssl::{
2525
};
2626

2727
mod sys {
28-
use libc::{c_char, c_int};
28+
use libc::{c_char, c_double, c_int, c_void};
2929
pub use openssl_sys::*;
3030
extern "C" {
3131
pub fn OBJ_txt2obj(s: *const c_char, no_name: c_int) -> *mut ASN1_OBJECT;
@@ -38,6 +38,8 @@ mod sys {
3838
pub fn X509_get_default_cert_dir_env() -> *const c_char;
3939
pub fn X509_get_default_cert_dir() -> *const c_char;
4040
pub fn SSL_CTX_set_post_handshake_auth(ctx: *mut SSL_CTX, val: c_int);
41+
pub fn RAND_add(buf: *const c_void, num: c_int, randomness: c_double);
42+
pub fn RAND_pseudo_bytes(buf: *const u8, num: c_int) -> c_int;
4143
}
4244
}
4345

@@ -188,6 +190,44 @@ fn ssl_get_default_verify_paths() -> (String, String, String, String) {
188190
}
189191
}
190192

193+
fn ssl_rand_status() -> i32 {
194+
unsafe { sys::RAND_status() }
195+
}
196+
197+
fn ssl_rand_add(string: Either<PyStringRef, PyBytesLike>, entropy: f64) {
198+
let f = |b: &[u8]| {
199+
for buf in b.chunks(libc::c_int::max_value() as usize) {
200+
unsafe { sys::RAND_add(buf.as_ptr() as *const _, buf.len() as _, entropy) }
201+
}
202+
};
203+
match string {
204+
Either::A(s) => f(s.as_str().as_bytes()),
205+
Either::B(b) => b.with_ref(f),
206+
}
207+
}
208+
209+
fn ssl_rand_bytes(n: i32, vm: &VirtualMachine) -> PyResult<Vec<u8>> {
210+
if n < 0 {
211+
return Err(vm.new_value_error("num must be positive".to_owned()));
212+
}
213+
let mut buf = vec![0; n as usize];
214+
openssl::rand::rand_bytes(&mut buf)
215+
.map(|()| buf)
216+
.map_err(|e| convert_openssl_error(vm, e))
217+
}
218+
219+
fn ssl_rand_pseudo_bytes(n: i32, vm: &VirtualMachine) -> PyResult<(Vec<u8>, bool)> {
220+
if n < 0 {
221+
return Err(vm.new_value_error("num must be positive".to_owned()));
222+
}
223+
let mut buf = vec![0; n as usize];
224+
let ret = unsafe { sys::RAND_pseudo_bytes(buf.as_mut_ptr(), n) };
225+
match ret {
226+
0 | 1 => Ok((buf, ret == 1)),
227+
_ => Err(convert_openssl_error(vm, openssl::error::ErrorStack::get())),
228+
}
229+
}
230+
191231
#[pyclass(name = "_SSLContext")]
192232
struct PySslContext {
193233
ctx: RefCell<SslContextBuilder>,
@@ -500,7 +540,6 @@ impl PySslSocket {
500540

501541
#[pymethod]
502542
fn do_handshake(&self, vm: &VirtualMachine) -> PyResult<()> {
503-
use crate::pyobject::Either;
504543
// Either a stream builder or a mid-handshake stream from WANT_READ or WANT_WRITE
505544
let mut handshaker: Either<_, ssl::MidHandshakeSslStream<_>> =
506545
Either::A(self.stream_builder());
@@ -605,6 +644,10 @@ pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {
605644
"txt2obj" => ctx.new_function(ssl_txt2obj),
606645
"nid2obj" => ctx.new_function(ssl_nid2obj),
607646
"get_default_verify_paths" => ctx.new_function(ssl_get_default_verify_paths),
647+
"RAND_status" => ctx.new_function(ssl_rand_status),
648+
"RAND_add" => ctx.new_function(ssl_rand_add),
649+
"RAND_bytes" => ctx.new_function(ssl_rand_bytes),
650+
"RAND_pseudo_bytes" => ctx.new_function(ssl_rand_pseudo_bytes),
608651

609652
// Constants
610653
"OPENSSL_VERSION" => ctx.new_str(openssl::version::version().to_owned()),

0 commit comments

Comments
 (0)