Skip to content

Commit

Permalink
Implement SSL_get_peer_signature_type_nid
Browse files Browse the repository at this point in the history
  • Loading branch information
cpu committed May 3, 2024
1 parent 3a08253 commit 914f477
Show file tree
Hide file tree
Showing 8 changed files with 92 additions and 4 deletions.
2 changes: 1 addition & 1 deletion rustls-libssl/MATRIX.md
Original file line number Diff line number Diff line change
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
1 change: 1 addition & 0 deletions rustls-libssl/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,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),
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,
}
}
22 changes: 22 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 @@ -1130,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
10 changes: 9 additions & 1 deletion rustls-libssl/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ 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;
Expand Down Expand Up @@ -1345,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
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

0 comments on commit 914f477

Please sign in to comment.