@@ -13,7 +13,7 @@ use std::{
1313 cell:: RefCell ,
1414 ffi:: { CStr , CString } ,
1515 fmt:: { self , Debug , Display , Formatter } ,
16- mem:: MaybeUninit ,
16+ mem:: { size_of , MaybeUninit } ,
1717 ops:: { Deref , DerefMut } ,
1818 os:: raw:: { c_uint, c_void} ,
1919 pin:: Pin ,
@@ -414,7 +414,6 @@ impl SecretAgentInfo {
414414 pub const fn alpn ( & self ) -> Option < & String > {
415415 self . alpn . as_ref ( )
416416 }
417- // TODO: Not used in neqo, but Gecko calls it. Needs a test to call it.
418417 #[ must_use]
419418 pub const fn signature_scheme ( & self ) -> SignatureScheme {
420419 self . signature_scheme
@@ -1256,6 +1255,17 @@ pub struct Server {
12561255 zero_rtt_check : Option < Pin < Box < ZeroRttCheckState > > > ,
12571256}
12581257
1258+ fn load_cert_and_key ( name : & str ) -> Res < ( p11:: Certificate , PrivateKey ) > {
1259+ let c = CString :: new ( name) ?;
1260+ let cert = p11:: Certificate :: from_ptr ( unsafe {
1261+ p11:: PK11_FindCertFromNickname ( c. as_ptr ( ) , null_mut ( ) )
1262+ } )
1263+ . map_err ( |_| Error :: CertificateLoading ) ?;
1264+ let key = PrivateKey :: from_ptr ( unsafe { p11:: PK11_FindKeyByAnyCert ( * cert, null_mut ( ) ) } )
1265+ . map_err ( |_| Error :: CertificateLoading ) ?;
1266+ Ok ( ( cert, key) )
1267+ }
1268+
12591269impl Server {
12601270 /// Create a new server agent.
12611271 ///
@@ -1264,22 +1274,63 @@ impl Server {
12641274 /// Errors returned when NSS fails.
12651275 pub fn new < A : AsRef < str > > ( certificates : & [ A ] ) -> Res < Self > {
12661276 let mut agent = SecretAgent :: new ( ) ?;
1277+ for n in certificates {
1278+ let ( cert, key) = load_cert_and_key ( n. as_ref ( ) ) ?;
1279+ secstatus_to_res ( unsafe {
1280+ ssl:: SSL_ConfigServerCert ( agent. fd , ( * cert) . cast ( ) , ( * key) . cast ( ) , null ( ) , 0 )
1281+ } ) ?;
1282+ }
1283+ agent. ready ( true , true ) ?;
1284+ Ok ( Self {
1285+ agent,
1286+ zero_rtt_check : None ,
1287+ } )
1288+ }
12671289
1290+ /// Create a server with OCSP responses and SCTs configured.
1291+ /// Not suitable for multiple certificates, because it configures the same OCSP/SCT for all
1292+ /// certificates. In other words, this is good for testing that the plumbing works, not for
1293+ /// a real server.
1294+ ///
1295+ /// # Errors
1296+ ///
1297+ /// Errors returned when NSS fails.
1298+ pub fn new_with_ocsp_and_scts < A : AsRef < str > > (
1299+ certificates : & [ A ] ,
1300+ ocsp_responses : & [ & [ u8 ] ] ,
1301+ scts : & [ u8 ] ,
1302+ ) -> Res < Self > {
1303+ let mut agent = SecretAgent :: new ( ) ?;
12681304 for n in certificates {
1269- let c = CString :: new ( n. as_ref ( ) ) ?;
1270- let cert_ptr = unsafe { p11:: PK11_FindCertFromNickname ( c. as_ptr ( ) , null_mut ( ) ) } ;
1271- let Ok ( cert) = p11:: Certificate :: from_ptr ( cert_ptr) else {
1272- return Err ( Error :: CertificateLoading ) ;
1305+ let ( cert, key) = load_cert_and_key ( n. as_ref ( ) ) ?;
1306+ let ocsp_items: Vec < p11:: SECItem > = ocsp_responses
1307+ . iter ( )
1308+ . map ( |b| p11:: Item :: wrap ( b) )
1309+ . collect :: < Res < _ > > ( ) ?;
1310+ let ocsp_array = ssl:: SECItemArrayStr {
1311+ items : ocsp_items. as_ptr ( ) . cast :: < ssl:: SECItem > ( ) . cast_mut ( ) ,
1312+ len : c_uint:: try_from ( ocsp_items. len ( ) ) ?,
12731313 } ;
1274- let key_ptr = unsafe { p11:: PK11_FindKeyByAnyCert ( * cert, null_mut ( ) ) } ;
1275- let Ok ( key) = PrivateKey :: from_ptr ( key_ptr) else {
1276- return Err ( Error :: CertificateLoading ) ;
1314+ let sct_item = p11:: Item :: wrap ( scts) ?;
1315+ let extra = ssl:: SSLExtraServerCertDataStr {
1316+ // ssl_auth_null means "I don't care what sort of certificate this is".
1317+ authType : ssl:: SSLAuthType :: ssl_auth_null,
1318+ certChain : null ( ) ,
1319+ stapledOCSPResponses : & ocsp_array,
1320+ signedCertTimestamps : std:: ptr:: from_ref ( & sct_item) . cast ( ) ,
1321+ delegCred : null ( ) ,
1322+ delegCredPrivKey : null ( ) ,
12771323 } ;
12781324 secstatus_to_res ( unsafe {
1279- ssl:: SSL_ConfigServerCert ( agent. fd , ( * cert) . cast ( ) , ( * key) . cast ( ) , null ( ) , 0 )
1325+ ssl:: SSL_ConfigServerCert (
1326+ agent. fd ,
1327+ ( * cert) . cast ( ) ,
1328+ ( * key) . cast ( ) ,
1329+ & extra,
1330+ c_uint:: try_from ( size_of :: < ssl:: SSLExtraServerCertDataStr > ( ) ) ?,
1331+ )
12801332 } ) ?;
12811333 }
1282-
12831334 agent. ready ( true , true ) ?;
12841335 Ok ( Self {
12851336 agent,
0 commit comments