Skip to content

Commit a37c9c8

Browse files
committed
Add ssl.RAND_* functions
1 parent b803496 commit a37c9c8

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

@@ -190,6 +192,44 @@ fn ssl_get_default_verify_paths() -> (String, String, String, String) {
190192
}
191193
}
192194

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

503543
#[pymethod]
504544
fn do_handshake(&self, vm: &VirtualMachine) -> PyResult<()> {
505-
use crate::pyobject::Either;
506545
// Either a stream builder or a mid-handshake stream from WANT_READ or WANT_WRITE
507546
let mut handshaker: Either<_, ssl::MidHandshakeSslStream<_>> =
508547
Either::A(self.stream_builder());
@@ -607,6 +646,10 @@ pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {
607646
"txt2obj" => ctx.new_function(ssl_txt2obj),
608647
"nid2obj" => ctx.new_function(ssl_nid2obj),
609648
"get_default_verify_paths" => ctx.new_function(ssl_get_default_verify_paths),
649+
"RAND_status" => ctx.new_function(ssl_rand_status),
650+
"RAND_add" => ctx.new_function(ssl_rand_add),
651+
"RAND_bytes" => ctx.new_function(ssl_rand_bytes),
652+
"RAND_pseudo_bytes" => ctx.new_function(ssl_rand_pseudo_bytes),
610653

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

0 commit comments

Comments
 (0)