Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Starting support for curl 8.5.0 #21

Merged
merged 2 commits into from
May 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions rustls-libssl/MATRIX.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@
| `SSL_CTX_set_async_callback_arg` | | | |
| `SSL_CTX_set_block_padding` | | | |
| `SSL_CTX_set_cert_cb` | | :white_check_mark: | :white_check_mark: |
| `SSL_CTX_set_cert_store` | | | |
| `SSL_CTX_set_cert_store` | | | :white_check_mark: |
| `SSL_CTX_set_cert_verify_callback` | | | |
| `SSL_CTX_set_cipher_list` | :white_check_mark: | :white_check_mark: | :white_check_mark: |
| `SSL_CTX_set_ciphersuites` | :white_check_mark: | | :exclamation: [^stub] |
Expand Down Expand Up @@ -347,7 +347,7 @@
| `SSL_get_options` | | :white_check_mark: | :white_check_mark: |
| `SSL_get_peer_cert_chain` | :white_check_mark: | | :white_check_mark: |
| `SSL_get_peer_finished` | | | |
| `SSL_get_peer_signature_type_nid` | | | |
| `SSL_get_peer_signature_type_nid` | | | :white_check_mark: |
| `SSL_get_pending_cipher` | | | |
| `SSL_get_privatekey` | :white_check_mark: | | :white_check_mark: |
| `SSL_get_psk_identity` [^psk] | | | |
Expand Down
2 changes: 2 additions & 0 deletions rustls-libssl/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ const ENTRYPOINTS: &[&str] = &[
"SSL_CTX_set_alpn_protos",
"SSL_CTX_set_alpn_select_cb",
"SSL_CTX_set_cert_cb",
"SSL_CTX_set_cert_store",
"SSL_CTX_set_cipher_list",
"SSL_CTX_set_ciphersuites",
"SSL_CTX_set_client_CA_list",
Expand Down Expand Up @@ -142,6 +143,7 @@ const ENTRYPOINTS: &[&str] = &[
"SSL_get_ex_data_X509_STORE_CTX_idx",
"SSL_get_options",
"SSL_get_peer_cert_chain",
"SSL_get_peer_signature_type_nid",
"SSL_get_privatekey",
"SSL_get_rbio",
"SSL_get_servername",
Expand Down
21 changes: 20 additions & 1 deletion rustls-libssl/src/constants.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
use core::ffi::{c_int, CStr};
use openssl_sys::{
NID_X9_62_prime256v1, NID_rsaEncryption, NID_rsassaPss, NID_secp384r1, NID_secp521r1,
NID_ED25519, NID_ED448,
};

use rustls::AlertDescription;
use rustls::{AlertDescription, SignatureScheme};

pub fn alert_desc_to_long_string(value: c_int) -> &'static CStr {
match AlertDescription::from(value as u8) {
Expand Down Expand Up @@ -83,3 +87,18 @@ pub fn alert_desc_to_short_string(value: c_int) -> &'static CStr {
_ => c"UK",
}
}

pub fn sig_scheme_to_nid(scheme: SignatureScheme) -> Option<c_int> {
use SignatureScheme::*;
match scheme {
RSA_PKCS1_SHA256 | RSA_PKCS1_SHA384 | RSA_PKCS1_SHA512 => Some(NID_rsaEncryption),
RSA_PSS_SHA256 | RSA_PSS_SHA384 | RSA_PSS_SHA512 => Some(NID_rsassaPss),
cpu marked this conversation as resolved.
Show resolved Hide resolved
ECDSA_NISTP256_SHA256 => Some(NID_X9_62_prime256v1),
ECDSA_NISTP384_SHA384 => Some(NID_secp384r1),
ECDSA_NISTP521_SHA512 => Some(NID_secp521r1),
ED25519 => Some(NID_ED25519),
ED448 => Some(NID_ED448),
// Omitted: SHA1 legacy schemes.
_ => None,
}
}
28 changes: 28 additions & 0 deletions rustls-libssl/src/entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ use rustls::pki_types::{CertificateDer, PrivatePkcs8KeyDer};

use crate::bio::{Bio, BIO, BIO_METHOD};
use crate::callbacks::SslCallbackContext;
use crate::constants::sig_scheme_to_nid;
use crate::error::{ffi_panic_boundary, Error, MysteriouslyOppositeReturnValue};
use crate::evp_pkey::EvpPkey;
use crate::ex_data::ExData;
Expand Down Expand Up @@ -297,6 +298,12 @@ entry! {
}
}

entry! {
pub fn _SSL_CTX_set_cert_store(ctx: *mut SSL_CTX, store: *mut X509_STORE) {
try_clone_arc!(ctx).get_mut().set_x509_store(store);
}
}

fn load_verify_files(
ctx: &NotThreadSafe<SSL_CTX>,
file_names: impl Iterator<Item = PathBuf>,
Expand Down Expand Up @@ -1124,6 +1131,27 @@ entry! {
}
}

entry! {
pub fn _SSL_get_peer_signature_type_nid(ssl: *const SSL, psigtype_nid: *mut c_int) -> c_int {
if psigtype_nid.is_null() {
return 0;
}

let sigalg_nid = try_clone_arc!(ssl)
.get()
.get_last_verification_sig_scheme()
.and_then(sig_scheme_to_nid);

match sigalg_nid {
Some(nid) => {
unsafe { ptr::write(psigtype_nid, nid) };
C_INT_SUCCESS
}
None => 0,
}
}
}

entry! {
pub fn _SSL_get0_verified_chain(ssl: *const SSL) -> *mut stack_st_X509 {
_SSL_get_peer_cert_chain(ssl)
Expand Down
20 changes: 18 additions & 2 deletions rustls-libssl/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,11 @@ use rustls::pki_types::{CertificateDer, ServerName};
use rustls::server::{Accepted, Acceptor};
use rustls::{
CipherSuite, ClientConfig, ClientConnection, Connection, HandshakeKind, ProtocolVersion,
RootCertStore, ServerConfig, SupportedProtocolVersion,
RootCertStore, ServerConfig, SignatureScheme, SupportedProtocolVersion,
};

use not_thread_safe::NotThreadSafe;
use x509::OwnedX509Store;

mod bio;
mod cache;
Expand Down Expand Up @@ -435,7 +436,7 @@ impl SslContext {
verify_mode: VerifyMode::default(),
verify_depth: -1,
verify_roots: RootCertStore::empty(),
verify_x509_store: x509::OwnedX509Store::new(),
verify_x509_store: OwnedX509Store::default(),
alpn: vec![],
default_cert_file: None,
default_cert_dir: None,
Expand Down Expand Up @@ -615,6 +616,13 @@ impl SslContext {
self.verify_x509_store.pointer()
}

fn set_x509_store(&mut self, store: *mut X509_STORE) {
self.verify_x509_store = match store.is_null() {
true => OwnedX509Store::default(),
false => OwnedX509Store::new(store),
cpu marked this conversation as resolved.
Show resolved Hide resolved
};
}

fn set_alpn_offer(&mut self, alpn: Vec<Vec<u8>>) {
self.alpn = alpn;
}
Expand Down Expand Up @@ -1337,6 +1345,14 @@ impl Ssl {
}
}

fn get_last_verification_sig_scheme(&self) -> Option<SignatureScheme> {
match &self.conn {
ConnState::Client(_, verifier) => verifier.last_sig_scheme(),
ConnState::Server(_, verifier, _) => verifier.last_sig_scheme(),
_ => None,
}
}

fn get_error(&mut self) -> c_int {
match self.conn_mut() {
Some(conn) => {
Expand Down
31 changes: 30 additions & 1 deletion rustls-libssl/src/verifier.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use core::sync::atomic::{AtomicI64, Ordering};
use std::sync::Arc;
use std::sync::{Arc, RwLock};

use openssl_sys::{
X509_V_ERR_CERT_HAS_EXPIRED, X509_V_ERR_CERT_NOT_YET_VALID, X509_V_ERR_CERT_REVOKED,
Expand Down Expand Up @@ -41,6 +41,8 @@ pub struct ServerVerifier {
mode: VerifyMode,

last_result: AtomicI64,

last_sig_scheme: RwLock<Option<SignatureScheme>>,
}

impl ServerVerifier {
Expand All @@ -56,13 +58,18 @@ impl ServerVerifier {
verify_hostname: hostname.clone(),
mode,
last_result: AtomicI64::new(X509_V_ERR_UNSPECIFIED as i64),
last_sig_scheme: RwLock::new(None),
}
}

pub fn last_result(&self) -> i64 {
self.last_result.load(Ordering::Acquire)
}

pub fn last_sig_scheme(&self) -> Option<SignatureScheme> {
self.last_sig_scheme.read().ok().map(|scheme| *scheme)?
}

fn verify_server_cert_inner(
&self,
end_entity: &CertificateDer<'_>,
Expand All @@ -85,6 +92,12 @@ impl ServerVerifier {

Ok(())
}

fn update_sig_scheme(&self, scheme: SignatureScheme) {
if let Ok(mut last_scheme) = self.last_sig_scheme.write() {
*last_scheme = Some(scheme);
}
}
}

impl ServerCertVerifier for ServerVerifier {
Expand Down Expand Up @@ -115,6 +128,7 @@ impl ServerCertVerifier for ServerVerifier {
cert: &CertificateDer<'_>,
dss: &DigitallySignedStruct,
) -> Result<HandshakeSignatureValid, Error> {
self.update_sig_scheme(dss.scheme);
verify_tls12_signature(
message,
cert,
Expand All @@ -129,6 +143,7 @@ impl ServerCertVerifier for ServerVerifier {
cert: &CertificateDer<'_>,
dss: &DigitallySignedStruct,
) -> Result<HandshakeSignatureValid, Error> {
self.update_sig_scheme(dss.scheme);
verify_tls13_signature(
message,
cert,
Expand All @@ -149,6 +164,7 @@ pub struct ClientVerifier {
parent: Arc<dyn ClientCertVerifier>,
mode: VerifyMode,
last_result: AtomicI64,
last_sig_scheme: RwLock<Option<SignatureScheme>>,
}

impl ClientVerifier {
Expand Down Expand Up @@ -178,12 +194,23 @@ impl ClientVerifier {
parent,
mode,
last_result: AtomicI64::new(initial_result as i64),
last_sig_scheme: RwLock::new(None),
})
}

pub fn last_result(&self) -> i64 {
self.last_result.load(Ordering::Acquire)
}

pub fn last_sig_scheme(&self) -> Option<SignatureScheme> {
self.last_sig_scheme.read().ok().map(|scheme| *scheme)?
}

fn update_sig_scheme(&self, scheme: SignatureScheme) {
if let Ok(mut last_scheme) = self.last_sig_scheme.write() {
*last_scheme = Some(scheme);
}
}
}

impl ClientCertVerifier for ClientVerifier {
Expand Down Expand Up @@ -223,6 +250,7 @@ impl ClientCertVerifier for ClientVerifier {
cert: &CertificateDer<'_>,
dss: &DigitallySignedStruct,
) -> Result<HandshakeSignatureValid, Error> {
self.update_sig_scheme(dss.scheme);
self.parent.verify_tls12_signature(message, cert, dss)
}

Expand All @@ -232,6 +260,7 @@ impl ClientCertVerifier for ClientVerifier {
cert: &CertificateDer<'_>,
dss: &DigitallySignedStruct,
) -> Result<HandshakeSignatureValid, Error> {
self.update_sig_scheme(dss.scheme);
self.parent.verify_tls13_signature(message, cert, dss)
}

Expand Down
15 changes: 11 additions & 4 deletions rustls-libssl/src/x509.rs
Original file line number Diff line number Diff line change
Expand Up @@ -237,17 +237,24 @@ pub struct OwnedX509Store {
}

impl OwnedX509Store {
pub fn new() -> Self {
Self {
raw: unsafe { X509_STORE_new() },
}
/// Create a new one, from a (donated) existing ref.
pub fn new(store: *mut X509_STORE) -> Self {
Self { raw: store }
}

pub fn pointer(&self) -> *mut X509_STORE {
self.raw
}
}

impl Default for OwnedX509Store {
fn default() -> Self {
Self {
raw: unsafe { X509_STORE_new() },
}
}
}

impl Drop for OwnedX509Store {
fn drop(&mut self) {
unsafe {
Expand Down
4 changes: 4 additions & 0 deletions rustls-libssl/tests/client.c
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,10 @@ int main(int argc, char **argv) {
printf("numeric version: %d\n", SSL_version(ssl));
printf("verify-result: %ld\n", SSL_get_verify_result(ssl));
printf("cipher: %s\n", SSL_CIPHER_standard_name(SSL_get_current_cipher(ssl)));
int cipher_nid = 0;
TRACE(SSL_get_peer_signature_type_nid(ssl, &cipher_nid));
dump_openssl_error_stack();
printf("cipher NID: %d\n", cipher_nid);

show_peer_certificate("server", ssl);

Expand Down
5 changes: 5 additions & 0 deletions rustls-libssl/tests/server.c
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,11 @@ int main(int argc, char **argv) {
printf("numeric version: %d\n", SSL_version(ssl));
printf("verify-result: %ld\n", SSL_get_verify_result(ssl));
printf("cipher: %s\n", SSL_CIPHER_standard_name(SSL_get_current_cipher(ssl)));
int cipher_nid = 0;
TRACE(SSL_get_peer_signature_type_nid(ssl, &cipher_nid));
dump_openssl_error_stack();
printf("cipher NID: %d\n", cipher_nid);

printf("SSL_get_servername: %s (%d)\n",
SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name),
SSL_get_servername_type(ssl));
Expand Down