Skip to content

Commit 914f477

Browse files
committed
Implement SSL_get_peer_signature_type_nid
1 parent 3a08253 commit 914f477

File tree

8 files changed

+92
-4
lines changed

8 files changed

+92
-4
lines changed

rustls-libssl/MATRIX.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -347,7 +347,7 @@
347347
| `SSL_get_options` | | :white_check_mark: | :white_check_mark: |
348348
| `SSL_get_peer_cert_chain` | :white_check_mark: | | :white_check_mark: |
349349
| `SSL_get_peer_finished` | | | |
350-
| `SSL_get_peer_signature_type_nid` | | | |
350+
| `SSL_get_peer_signature_type_nid` | | | :white_check_mark: |
351351
| `SSL_get_pending_cipher` | | | |
352352
| `SSL_get_privatekey` | :white_check_mark: | | :white_check_mark: |
353353
| `SSL_get_psk_identity` [^psk] | | | |

rustls-libssl/build.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ const ENTRYPOINTS: &[&str] = &[
143143
"SSL_get_ex_data_X509_STORE_CTX_idx",
144144
"SSL_get_options",
145145
"SSL_get_peer_cert_chain",
146+
"SSL_get_peer_signature_type_nid",
146147
"SSL_get_privatekey",
147148
"SSL_get_rbio",
148149
"SSL_get_servername",

rustls-libssl/src/constants.rs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
use core::ffi::{c_int, CStr};
2+
use openssl_sys::{
3+
NID_X9_62_prime256v1, NID_rsaEncryption, NID_rsassaPss, NID_secp384r1, NID_secp521r1,
4+
NID_ED25519, NID_ED448,
5+
};
26

3-
use rustls::AlertDescription;
7+
use rustls::{AlertDescription, SignatureScheme};
48

59
pub fn alert_desc_to_long_string(value: c_int) -> &'static CStr {
610
match AlertDescription::from(value as u8) {
@@ -83,3 +87,18 @@ pub fn alert_desc_to_short_string(value: c_int) -> &'static CStr {
8387
_ => c"UK",
8488
}
8589
}
90+
91+
pub fn sig_scheme_to_nid(scheme: SignatureScheme) -> Option<c_int> {
92+
use SignatureScheme::*;
93+
match scheme {
94+
RSA_PKCS1_SHA256 | RSA_PKCS1_SHA384 | RSA_PKCS1_SHA512 => Some(NID_rsaEncryption),
95+
RSA_PSS_SHA256 | RSA_PSS_SHA384 | RSA_PSS_SHA512 => Some(NID_rsassaPss),
96+
ECDSA_NISTP256_SHA256 => Some(NID_X9_62_prime256v1),
97+
ECDSA_NISTP384_SHA384 => Some(NID_secp384r1),
98+
ECDSA_NISTP521_SHA512 => Some(NID_secp521r1),
99+
ED25519 => Some(NID_ED25519),
100+
ED448 => Some(NID_ED448),
101+
// Omitted: SHA1 legacy schemes.
102+
_ => None,
103+
}
104+
}

rustls-libssl/src/entry.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ use rustls::pki_types::{CertificateDer, PrivatePkcs8KeyDer};
1717

1818
use crate::bio::{Bio, BIO, BIO_METHOD};
1919
use crate::callbacks::SslCallbackContext;
20+
use crate::constants::sig_scheme_to_nid;
2021
use crate::error::{ffi_panic_boundary, Error, MysteriouslyOppositeReturnValue};
2122
use crate::evp_pkey::EvpPkey;
2223
use crate::ex_data::ExData;
@@ -1130,6 +1131,27 @@ entry! {
11301131
}
11311132
}
11321133

1134+
entry! {
1135+
pub fn _SSL_get_peer_signature_type_nid(ssl: *const SSL, psigtype_nid: *mut c_int) -> c_int {
1136+
if psigtype_nid.is_null() {
1137+
return 0;
1138+
}
1139+
1140+
let sigalg_nid = try_clone_arc!(ssl)
1141+
.get()
1142+
.get_last_verification_sig_scheme()
1143+
.and_then(sig_scheme_to_nid);
1144+
1145+
match sigalg_nid {
1146+
Some(nid) => {
1147+
unsafe { ptr::write(psigtype_nid, nid) };
1148+
C_INT_SUCCESS
1149+
}
1150+
None => 0,
1151+
}
1152+
}
1153+
}
1154+
11331155
entry! {
11341156
pub fn _SSL_get0_verified_chain(ssl: *const SSL) -> *mut stack_st_X509 {
11351157
_SSL_get_peer_cert_chain(ssl)

rustls-libssl/src/lib.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use rustls::pki_types::{CertificateDer, ServerName};
1717
use rustls::server::{Accepted, Acceptor};
1818
use rustls::{
1919
CipherSuite, ClientConfig, ClientConnection, Connection, HandshakeKind, ProtocolVersion,
20-
RootCertStore, ServerConfig, SupportedProtocolVersion,
20+
RootCertStore, ServerConfig, SignatureScheme, SupportedProtocolVersion,
2121
};
2222

2323
use not_thread_safe::NotThreadSafe;
@@ -1345,6 +1345,14 @@ impl Ssl {
13451345
}
13461346
}
13471347

1348+
fn get_last_verification_sig_scheme(&self) -> Option<SignatureScheme> {
1349+
match &self.conn {
1350+
ConnState::Client(_, verifier) => verifier.last_sig_scheme(),
1351+
ConnState::Server(_, verifier, _) => verifier.last_sig_scheme(),
1352+
_ => None,
1353+
}
1354+
}
1355+
13481356
fn get_error(&mut self) -> c_int {
13491357
match self.conn_mut() {
13501358
Some(conn) => {

rustls-libssl/src/verifier.rs

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use core::sync::atomic::{AtomicI64, Ordering};
2-
use std::sync::Arc;
2+
use std::sync::{Arc, RwLock};
33

44
use openssl_sys::{
55
X509_V_ERR_CERT_HAS_EXPIRED, X509_V_ERR_CERT_NOT_YET_VALID, X509_V_ERR_CERT_REVOKED,
@@ -41,6 +41,8 @@ pub struct ServerVerifier {
4141
mode: VerifyMode,
4242

4343
last_result: AtomicI64,
44+
45+
last_sig_scheme: RwLock<Option<SignatureScheme>>,
4446
}
4547

4648
impl ServerVerifier {
@@ -56,13 +58,18 @@ impl ServerVerifier {
5658
verify_hostname: hostname.clone(),
5759
mode,
5860
last_result: AtomicI64::new(X509_V_ERR_UNSPECIFIED as i64),
61+
last_sig_scheme: RwLock::new(None),
5962
}
6063
}
6164

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

69+
pub fn last_sig_scheme(&self) -> Option<SignatureScheme> {
70+
self.last_sig_scheme.read().ok().map(|scheme| *scheme)?
71+
}
72+
6673
fn verify_server_cert_inner(
6774
&self,
6875
end_entity: &CertificateDer<'_>,
@@ -85,6 +92,12 @@ impl ServerVerifier {
8592

8693
Ok(())
8794
}
95+
96+
fn update_sig_scheme(&self, scheme: SignatureScheme) {
97+
if let Ok(mut last_scheme) = self.last_sig_scheme.write() {
98+
*last_scheme = Some(scheme);
99+
}
100+
}
88101
}
89102

90103
impl ServerCertVerifier for ServerVerifier {
@@ -115,6 +128,7 @@ impl ServerCertVerifier for ServerVerifier {
115128
cert: &CertificateDer<'_>,
116129
dss: &DigitallySignedStruct,
117130
) -> Result<HandshakeSignatureValid, Error> {
131+
self.update_sig_scheme(dss.scheme);
118132
verify_tls12_signature(
119133
message,
120134
cert,
@@ -129,6 +143,7 @@ impl ServerCertVerifier for ServerVerifier {
129143
cert: &CertificateDer<'_>,
130144
dss: &DigitallySignedStruct,
131145
) -> Result<HandshakeSignatureValid, Error> {
146+
self.update_sig_scheme(dss.scheme);
132147
verify_tls13_signature(
133148
message,
134149
cert,
@@ -149,6 +164,7 @@ pub struct ClientVerifier {
149164
parent: Arc<dyn ClientCertVerifier>,
150165
mode: VerifyMode,
151166
last_result: AtomicI64,
167+
last_sig_scheme: RwLock<Option<SignatureScheme>>,
152168
}
153169

154170
impl ClientVerifier {
@@ -178,12 +194,23 @@ impl ClientVerifier {
178194
parent,
179195
mode,
180196
last_result: AtomicI64::new(initial_result as i64),
197+
last_sig_scheme: RwLock::new(None),
181198
})
182199
}
183200

184201
pub fn last_result(&self) -> i64 {
185202
self.last_result.load(Ordering::Acquire)
186203
}
204+
205+
pub fn last_sig_scheme(&self) -> Option<SignatureScheme> {
206+
self.last_sig_scheme.read().ok().map(|scheme| *scheme)?
207+
}
208+
209+
fn update_sig_scheme(&self, scheme: SignatureScheme) {
210+
if let Ok(mut last_scheme) = self.last_sig_scheme.write() {
211+
*last_scheme = Some(scheme);
212+
}
213+
}
187214
}
188215

189216
impl ClientCertVerifier for ClientVerifier {
@@ -223,6 +250,7 @@ impl ClientCertVerifier for ClientVerifier {
223250
cert: &CertificateDer<'_>,
224251
dss: &DigitallySignedStruct,
225252
) -> Result<HandshakeSignatureValid, Error> {
253+
self.update_sig_scheme(dss.scheme);
226254
self.parent.verify_tls12_signature(message, cert, dss)
227255
}
228256

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

rustls-libssl/tests/client.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,10 @@ int main(int argc, char **argv) {
126126
printf("numeric version: %d\n", SSL_version(ssl));
127127
printf("verify-result: %ld\n", SSL_get_verify_result(ssl));
128128
printf("cipher: %s\n", SSL_CIPHER_standard_name(SSL_get_current_cipher(ssl)));
129+
int cipher_nid = 0;
130+
TRACE(SSL_get_peer_signature_type_nid(ssl, &cipher_nid));
131+
dump_openssl_error_stack();
132+
printf("cipher NID: %d\n", cipher_nid);
129133

130134
show_peer_certificate("server", ssl);
131135

rustls-libssl/tests/server.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,11 @@ int main(int argc, char **argv) {
202202
printf("numeric version: %d\n", SSL_version(ssl));
203203
printf("verify-result: %ld\n", SSL_get_verify_result(ssl));
204204
printf("cipher: %s\n", SSL_CIPHER_standard_name(SSL_get_current_cipher(ssl)));
205+
int cipher_nid = 0;
206+
TRACE(SSL_get_peer_signature_type_nid(ssl, &cipher_nid));
207+
dump_openssl_error_stack();
208+
printf("cipher NID: %d\n", cipher_nid);
209+
205210
printf("SSL_get_servername: %s (%d)\n",
206211
SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name),
207212
SSL_get_servername_type(ssl));

0 commit comments

Comments
 (0)