1use std::cmp::min;
2use std::fmt::Display;
3use std::sync::Arc;
4
5use libc::{c_char, c_uint, size_t};
6use rustls::server::VerifierBuilderError;
7use rustls::{
8 AlertDescription, CertRevocationListError, CertificateError, EncryptedClientHelloError, Error,
9 InconsistentKeys, InvalidMessage,
10};
11
12use crate::panic::ffi_panic_boundary;
13
14#[repr(transparent)]
20#[derive(Debug, Clone, Copy, PartialEq, Eq)]
21pub struct rustls_io_result(pub libc::c_int);
22
23macro_rules! u32_enum_builder {
24 (
25 $(#[$comment:meta])*
26 EnumName: $enum_name: ident;
27 EnumDefault: $enum_default: ident;
28 EnumVal { $( $enum_var: ident => $enum_val: expr ),* }
29 ) => {
30 $(#[$comment])*
31 #[allow(dead_code)]
32 #[repr(u32)]
33 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
34 pub enum $enum_name {
35 $( $enum_var = $enum_val),*
36 }
37 impl From<u32> for $enum_name {
38 fn from(x: u32) -> Self {
39 match x {
40 $($enum_val => $enum_name::$enum_var),*
41 , _ => $enum_name::$enum_default,
42 }
43 }
44 }
45 };
46}
47
48u32_enum_builder! {
49 EnumName: rustls_result;
51 EnumDefault: InvalidParameter;
52 EnumVal{
53 Ok => 7000,
54 Io => 7001,
55 NullParameter => 7002,
56 InvalidDnsNameError => 7003,
57 Panic => 7004,
58 CertificateParseError => 7005,
59 PrivateKeyParseError => 7006,
60 InsufficientSize => 7007,
61 NotFound => 7008,
62 InvalidParameter => 7009,
63 UnexpectedEof => 7010,
64 PlaintextEmpty => 7011,
65 AcceptorNotReady => 7012,
66 AlreadyUsed => 7013,
67 CertificateRevocationListParseError => 7014,
68 NoServerCertVerifier => 7015,
69 NoDefaultCryptoProvider => 7016,
70 GetRandomFailed => 7017,
71 NoCertResolver => 7018,
72 HpkeError => 7019,
73 BuilderIncompatibleTlsVersions => 7020,
74
75 NoCertificatesPresented => 7101,
77 DecryptError => 7102,
78 FailedToGetCurrentTime => 7103,
79 FailedToGetRandomBytes => 7113,
80 HandshakeNotComplete => 7104,
81 PeerSentOversizedRecord => 7105,
82 NoApplicationProtocol => 7106,
83 BadMaxFragmentSize => 7114,
84 UnsupportedNameType => 7115,
85 EncryptError => 7116,
86
87 CertEncodingBad => 7121,
98 CertExpired => 7122,
99 CertNotYetValid => 7123,
100 CertRevoked => 7124,
101 CertUnhandledCriticalExtension => 7125,
102 CertUnknownIssuer => 7126,
103 CertBadSignature => 7127,
104 CertNotValidForName => 7128,
105 CertInvalidPurpose => 7129,
106 CertApplicationVerificationFailure => 7130,
107 CertOtherError => 7131,
108 CertUnknownRevocationStatus => 7154,
109 CertExpiredRevocationList => 7156, MessageHandshakePayloadTooLarge => 7133,
114 MessageInvalidCcs => 7134,
115 MessageInvalidContentType => 7135,
116 MessageInvalidCertStatusType => 7136,
117 MessageInvalidCertRequest => 7137,
118 MessageInvalidDhParams => 7138,
119 MessageInvalidEmptyPayload => 7139,
120 MessageInvalidKeyUpdate => 7140,
121 MessageInvalidServerName => 7141,
122 MessageTooLarge => 7142,
123 MessageTooShort => 7143,
124 MessageMissingData => 7144,
125 MessageMissingKeyExchange => 7145,
126 MessageNoSignatureSchemes => 7146,
127 MessageTrailingData => 7147,
128 MessageUnexpectedMessage => 7148,
129 MessageUnknownProtocolVersion => 7149,
130 MessageUnsupportedCompression => 7150,
131 MessageUnsupportedCurveType => 7151,
132 MessageUnsupportedKeyExchangeAlgorithm => 7152,
133 MessageInvalidOther => 7153,
134 MessageCertificatePayloadTooLarge => 7155,
135
136 PeerIncompatibleError => 7107,
138 PeerMisbehavedError => 7108,
139 InappropriateMessage => 7109,
140 InappropriateHandshakeMessage => 7110,
141 General => 7112,
142
143 AlertCloseNotify => 7200,
146 AlertUnexpectedMessage => 7201,
147 AlertBadRecordMac => 7202,
148 AlertDecryptionFailed => 7203,
149 AlertRecordOverflow => 7204,
150 AlertDecompressionFailure => 7205,
151 AlertHandshakeFailure => 7206,
152 AlertNoCertificate => 7207,
153 AlertBadCertificate => 7208,
154 AlertUnsupportedCertificate => 7209,
155 AlertCertificateRevoked => 7210,
156 AlertCertificateExpired => 7211,
157 AlertCertificateUnknown => 7212,
158 AlertIllegalParameter => 7213,
159 AlertUnknownCA => 7214,
160 AlertAccessDenied => 7215,
161 AlertDecodeError => 7216,
162 AlertDecryptError => 7217,
163 AlertExportRestriction => 7218,
164 AlertProtocolVersion => 7219,
165 AlertInsufficientSecurity => 7220,
166 AlertInternalError => 7221,
167 AlertInappropriateFallback => 7222,
168 AlertUserCanceled => 7223,
169 AlertNoRenegotiation => 7224,
170 AlertMissingExtension => 7225,
171 AlertUnsupportedExtension => 7226,
172 AlertCertificateUnobtainable => 7227,
173 AlertUnrecognisedName => 7228,
174 AlertBadCertificateStatusResponse => 7229,
175 AlertBadCertificateHashValue => 7230,
176 AlertUnknownPSKIdentity => 7231,
177 AlertCertificateRequired => 7232,
178 AlertNoApplicationProtocol => 7233,
179 AlertUnknown => 7234,
180
181 CertRevocationListBadSignature => 7400,
191 CertRevocationListInvalidCrlNumber => 7401,
192 CertRevocationListInvalidRevokedCertSerialNumber => 7402,
193 CertRevocationListIssuerInvalidForCrl => 7403,
194 CertRevocationListOtherError => 7404,
195 CertRevocationListParseError => 7405,
196 CertRevocationListUnsupportedCrlVersion => 7406,
197 CertRevocationListUnsupportedCriticalExtension => 7407,
198 CertRevocationListUnsupportedDeltaCrl => 7408,
199 CertRevocationListUnsupportedIndirectCrl => 7409,
200 CertRevocationListUnsupportedRevocationReason => 7410,
201
202 ClientCertVerifierBuilderNoRootAnchors => 7500,
204
205 InconsistentKeysKeysMismatch => 7600,
207 InconsistentKeysUnknown => 7601,
208
209 InvalidEncryptedClientHelloInvalidConfigList => 7700,
211 InvalidEncryptedClientHelloNoCompatibleConfig => 7701,
212 InvalidEncryptedClientHelloSniRequired => 7702
213 }
214}
215
216impl rustls_result {
217 #[no_mangle]
224 pub extern "C" fn rustls_error(
225 result: c_uint,
226 buf: *mut c_char,
227 len: size_t,
228 out_n: *mut size_t,
229 ) {
230 ffi_panic_boundary! {
231 if buf.is_null() {
232 return;
233 }
234 if out_n.is_null() {
235 return;
236 }
237 let error_str = rustls_result::from(result).to_string();
238 let out_len = min(len, error_str.len());
239 unsafe {
240 std::ptr::copy_nonoverlapping(error_str.as_ptr() as *mut c_char, buf, out_len);
241 *out_n = out_len;
242 }
243 }
244 }
245
246 #[no_mangle]
248 pub extern "C" fn rustls_result_is_cert_error(result: c_uint) -> bool {
249 use rustls_result::*;
250 matches!(
251 rustls_result::from(result),
252 CertEncodingBad
253 | CertExpired
254 | CertNotYetValid
255 | CertRevoked
256 | CertUnhandledCriticalExtension
257 | CertUnknownIssuer
258 | CertUnknownRevocationStatus
259 | CertBadSignature
260 | CertNotValidForName
261 | CertInvalidPurpose
262 | CertApplicationVerificationFailure
263 | CertOtherError
264 )
265 }
266}
267
268impl Display for rustls_result {
269 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
270 use rustls::AlertDescription as alert;
271 use rustls_result::*;
272
273 match self {
274 Ok => write!(f, "OK"),
276 Io => write!(f, "I/O error"),
277 NullParameter => write!(f, "a parameter was NULL"),
278 InvalidDnsNameError => write!(
279 f,
280 "server name was malformed (not a valid hostname or IP address)"
281 ),
282 Panic => write!(f, "a Rust component panicked"),
283 CertificateParseError => write!(f, "error parsing certificate"),
284 PrivateKeyParseError => write!(f, "error parsing private key"),
285 InsufficientSize => write!(f, "provided buffer is of insufficient size"),
286 NotFound => write!(f, "the item was not found"),
287 InvalidParameter => write!(f, "a parameter had an invalid value"),
288 UnexpectedEof => write!(
289 f,
290 "peer closed TCP connection without first closing TLS connection"
291 ),
292 PlaintextEmpty => write!(
293 f,
294 "no plaintext available; call rustls_connection_read_tls again"
295 ),
296 AcceptorNotReady => write!(
297 f,
298 "rustls_acceptor not ready yet; read more TLS bytes into it"
299 ),
300 AlreadyUsed => write!(
301 f,
302 "tried to use a rustls struct after it had been converted to another struct"
303 ),
304 CertificateRevocationListParseError => {
305 write!(f, "error parsing certificate revocation list (CRL)",)
306 }
307 NoServerCertVerifier => {
308 write!(
309 f,
310 "no server certificate verifier was configured on the client config builder"
311 )
312 }
313 NoDefaultCryptoProvider => {
314 write!(
315 f,
316 "no default process-wide crypto provider has been installed"
317 )
318 }
319 GetRandomFailed => {
320 write!(f, "failed to get random bytes from the crypto provider")
321 }
322 NoCertResolver => {
323 write!(f, "no certificate resolver was configured")
324 }
325 HpkeError => {
326 write!(f, "an error occurred with the selected HPKE suite")
327 }
328 BuilderIncompatibleTlsVersions => {
329 write!(
330 f,
331 "the client config builder specifies incompatible TLS versions for the requested feature"
332 )
333 }
334
335 CertEncodingBad => Error::InvalidCertificate(CertificateError::BadEncoding).fmt(f),
336 CertExpired => Error::InvalidCertificate(CertificateError::Expired).fmt(f),
337 CertNotYetValid => Error::InvalidCertificate(CertificateError::NotValidYet).fmt(f),
338 CertRevoked => Error::InvalidCertificate(CertificateError::Revoked).fmt(f),
339 CertUnhandledCriticalExtension => {
340 Error::InvalidCertificate(CertificateError::UnhandledCriticalExtension).fmt(f)
341 }
342 CertUnknownIssuer => Error::InvalidCertificate(CertificateError::UnknownIssuer).fmt(f),
343 CertBadSignature => Error::InvalidCertificate(CertificateError::BadSignature).fmt(f),
344 CertNotValidForName => {
345 Error::InvalidCertificate(CertificateError::NotValidForName).fmt(f)
346 }
347 CertInvalidPurpose => {
348 Error::InvalidCertificate(CertificateError::InvalidPurpose).fmt(f)
349 }
350 CertApplicationVerificationFailure => {
351 Error::InvalidCertificate(CertificateError::ApplicationVerificationFailure).fmt(f)
352 }
353 CertUnknownRevocationStatus => {
354 Error::InvalidCertificate(CertificateError::UnknownRevocationStatus).fmt(f)
355 }
356 CertExpiredRevocationList => {
357 Error::InvalidCertificate(CertificateError::ExpiredRevocationList).fmt(f)
358 }
359 CertOtherError => write!(f, "unknown certificate error"),
360
361 InappropriateMessage => write!(f, "received unexpected message"),
365 InappropriateHandshakeMessage => write!(f, "received unexpected handshake message"),
366
367 MessageHandshakePayloadTooLarge => {
368 Error::InvalidMessage(InvalidMessage::HandshakePayloadTooLarge).fmt(f)
369 }
370 MessageCertificatePayloadTooLarge => {
371 Error::InvalidMessage(InvalidMessage::CertificatePayloadTooLarge).fmt(f)
372 }
373 MessageInvalidContentType => {
374 Error::InvalidMessage(InvalidMessage::InvalidContentType).fmt(f)
375 }
376 MessageInvalidServerName => {
377 Error::InvalidMessage(InvalidMessage::InvalidServerName).fmt(f)
378 }
379 MessageTooLarge => Error::InvalidMessage(InvalidMessage::MessageTooLarge).fmt(f),
380 MessageTooShort => Error::InvalidMessage(InvalidMessage::MessageTooShort).fmt(f),
381 MessageUnknownProtocolVersion => {
382 Error::InvalidMessage(InvalidMessage::UnknownProtocolVersion).fmt(f)
383 }
384 MessageUnsupportedCompression => {
385 Error::InvalidMessage(InvalidMessage::UnsupportedCompression).fmt(f)
386 }
387 MessageInvalidEmptyPayload => {
388 Error::InvalidMessage(InvalidMessage::InvalidEmptyPayload).fmt(f)
389 }
390 MessageInvalidCertStatusType => {
391 Error::InvalidMessage(InvalidMessage::InvalidCertificateStatusType).fmt(f)
392 }
393 MessageInvalidKeyUpdate => {
394 Error::InvalidMessage(InvalidMessage::InvalidKeyUpdate).fmt(f)
395 }
396 MessageUnsupportedCurveType => {
397 Error::InvalidMessage(InvalidMessage::UnsupportedCurveType).fmt(f)
398 }
399
400 MessageMissingData => write!(f, "missing data for the named handshake payload value"),
404 MessageTrailingData => write!(
405 f,
406 "trailing data found for the named handshake payload value"
407 ),
408 MessageUnexpectedMessage => write!(f, "peer sent unexpected message type"),
409 MessageUnsupportedKeyExchangeAlgorithm => {
410 write!(f, "peer sent an unsupported key exchange algorithm")
411 }
412
413 MessageMissingKeyExchange => {
416 write!(f, "peer did not advertise supported key exchange groups")
417 }
418 MessageNoSignatureSchemes => write!(f, "peer sent an empty list of signature schemes"),
419 MessageInvalidDhParams => write!(
420 f,
421 "peer's Diffie-Hellman (DH) parameters could not be decoded"
422 ),
423 MessageInvalidCertRequest => write!(f, "invalid certificate request context"),
424 MessageInvalidCcs => write!(f, "invalid change cipher spec (CCS) payload"),
425 MessageInvalidOther => write!(f, "invalid message"),
426
427 PeerIncompatibleError => write!(f, "peer is incompatible"),
428 PeerMisbehavedError => write!(f, "peer misbehaved"),
429
430 General => write!(f, "general error"),
431
432 NoCertificatesPresented => Error::NoCertificatesPresented.fmt(f),
433 DecryptError => Error::DecryptError.fmt(f),
434 FailedToGetCurrentTime => Error::FailedToGetCurrentTime.fmt(f),
435 FailedToGetRandomBytes => Error::FailedToGetRandomBytes.fmt(f),
436 HandshakeNotComplete => Error::HandshakeNotComplete.fmt(f),
437 PeerSentOversizedRecord => Error::PeerSentOversizedRecord.fmt(f),
438 NoApplicationProtocol => Error::NoApplicationProtocol.fmt(f),
439 BadMaxFragmentSize => Error::BadMaxFragmentSize.fmt(f),
440 UnsupportedNameType => Error::UnsupportedNameType.fmt(f),
441 EncryptError => Error::EncryptError.fmt(f),
442
443 AlertCloseNotify => Error::AlertReceived(alert::CloseNotify).fmt(f),
444 AlertUnexpectedMessage => Error::AlertReceived(alert::UnexpectedMessage).fmt(f),
445 AlertBadRecordMac => Error::AlertReceived(alert::BadRecordMac).fmt(f),
446 AlertDecryptionFailed => Error::AlertReceived(alert::DecryptionFailed).fmt(f),
447 AlertRecordOverflow => Error::AlertReceived(alert::RecordOverflow).fmt(f),
448 AlertDecompressionFailure => Error::AlertReceived(alert::DecompressionFailure).fmt(f),
449 AlertHandshakeFailure => Error::AlertReceived(alert::HandshakeFailure).fmt(f),
450 AlertNoCertificate => Error::AlertReceived(alert::NoCertificate).fmt(f),
451 AlertBadCertificate => Error::AlertReceived(alert::BadCertificate).fmt(f),
452 AlertUnsupportedCertificate => {
453 Error::AlertReceived(alert::UnsupportedCertificate).fmt(f)
454 }
455 AlertCertificateRevoked => Error::AlertReceived(alert::CertificateRevoked).fmt(f),
456 AlertCertificateExpired => Error::AlertReceived(alert::CertificateExpired).fmt(f),
457 AlertCertificateUnknown => Error::AlertReceived(alert::CertificateUnknown).fmt(f),
458 AlertIllegalParameter => Error::AlertReceived(alert::IllegalParameter).fmt(f),
459 AlertUnknownCA => Error::AlertReceived(alert::UnknownCA).fmt(f),
460 AlertAccessDenied => Error::AlertReceived(alert::AccessDenied).fmt(f),
461 AlertDecodeError => Error::AlertReceived(alert::DecodeError).fmt(f),
462 AlertDecryptError => Error::AlertReceived(alert::DecryptError).fmt(f),
463 AlertExportRestriction => Error::AlertReceived(alert::ExportRestriction).fmt(f),
464 AlertProtocolVersion => Error::AlertReceived(alert::ProtocolVersion).fmt(f),
465 AlertInsufficientSecurity => Error::AlertReceived(alert::InsufficientSecurity).fmt(f),
466 AlertInternalError => Error::AlertReceived(alert::InternalError).fmt(f),
467 AlertInappropriateFallback => Error::AlertReceived(alert::InappropriateFallback).fmt(f),
468 AlertUserCanceled => Error::AlertReceived(alert::UserCanceled).fmt(f),
469 AlertNoRenegotiation => Error::AlertReceived(alert::NoRenegotiation).fmt(f),
470 AlertMissingExtension => Error::AlertReceived(alert::MissingExtension).fmt(f),
471 AlertUnsupportedExtension => Error::AlertReceived(alert::UnsupportedExtension).fmt(f),
472 AlertCertificateUnobtainable => {
473 Error::AlertReceived(alert::CertificateUnobtainable).fmt(f)
474 }
475 AlertUnrecognisedName => Error::AlertReceived(alert::UnrecognisedName).fmt(f),
476 AlertBadCertificateStatusResponse => {
477 Error::AlertReceived(alert::BadCertificateStatusResponse).fmt(f)
478 }
479 AlertBadCertificateHashValue => {
480 Error::AlertReceived(alert::BadCertificateHashValue).fmt(f)
481 }
482 AlertUnknownPSKIdentity => Error::AlertReceived(alert::UnknownPSKIdentity).fmt(f),
483 AlertCertificateRequired => Error::AlertReceived(alert::CertificateRequired).fmt(f),
484 AlertNoApplicationProtocol => Error::AlertReceived(alert::NoApplicationProtocol).fmt(f),
485 AlertUnknown => Error::AlertReceived(alert::Unknown(0)).fmt(f),
486
487 CertRevocationListBadSignature => {
488 Error::InvalidCertRevocationList(CertRevocationListError::BadSignature).fmt(f)
489 }
490 CertRevocationListInvalidCrlNumber => {
491 Error::InvalidCertRevocationList(CertRevocationListError::InvalidCrlNumber).fmt(f)
492 }
493 CertRevocationListInvalidRevokedCertSerialNumber => Error::InvalidCertRevocationList(
494 CertRevocationListError::InvalidRevokedCertSerialNumber,
495 )
496 .fmt(f),
497 CertRevocationListIssuerInvalidForCrl => {
498 Error::InvalidCertRevocationList(CertRevocationListError::IssuerInvalidForCrl)
499 .fmt(f)
500 }
501 CertRevocationListOtherError => {
502 write!(f, "unknown certificate revocation list (CRL) error")
503 }
504 CertRevocationListParseError => {
505 Error::InvalidCertRevocationList(CertRevocationListError::ParseError).fmt(f)
506 }
507 CertRevocationListUnsupportedCrlVersion => {
508 Error::InvalidCertRevocationList(CertRevocationListError::UnsupportedCrlVersion)
509 .fmt(f)
510 }
511 CertRevocationListUnsupportedCriticalExtension => Error::InvalidCertRevocationList(
512 CertRevocationListError::UnsupportedCriticalExtension,
513 )
514 .fmt(f),
515 CertRevocationListUnsupportedDeltaCrl => {
516 Error::InvalidCertRevocationList(CertRevocationListError::UnsupportedDeltaCrl)
517 .fmt(f)
518 }
519 CertRevocationListUnsupportedIndirectCrl => {
520 Error::InvalidCertRevocationList(CertRevocationListError::UnsupportedIndirectCrl)
521 .fmt(f)
522 }
523 CertRevocationListUnsupportedRevocationReason => Error::InvalidCertRevocationList(
524 CertRevocationListError::UnsupportedRevocationReason,
525 )
526 .fmt(f),
527
528 ClientCertVerifierBuilderNoRootAnchors => write!(f, "no root trust anchors provided"),
529
530 InconsistentKeysKeysMismatch => {
531 Error::InconsistentKeys(InconsistentKeys::KeyMismatch).fmt(f)
532 }
533 InconsistentKeysUnknown => Error::InconsistentKeys(InconsistentKeys::Unknown).fmt(f),
534
535 InvalidEncryptedClientHelloInvalidConfigList => {
536 Error::InvalidEncryptedClientHello(EncryptedClientHelloError::InvalidConfigList)
537 .fmt(f)
538 }
539 InvalidEncryptedClientHelloNoCompatibleConfig => {
540 Error::InvalidEncryptedClientHello(EncryptedClientHelloError::NoCompatibleConfig)
541 .fmt(f)
542 }
543 InvalidEncryptedClientHelloSniRequired => {
544 Error::InvalidEncryptedClientHello(EncryptedClientHelloError::SniRequired).fmt(f)
545 }
546 }
547 }
548}
549
550pub(crate) fn map_error(input: Error) -> rustls_result {
551 use rustls_result::*;
552
553 match input {
554 Error::InappropriateMessage { .. } => InappropriateMessage,
555 Error::InappropriateHandshakeMessage { .. } => InappropriateHandshakeMessage,
556
557 Error::NoCertificatesPresented => NoCertificatesPresented,
558 Error::DecryptError => DecryptError,
559 Error::PeerIncompatible(_) => PeerIncompatibleError,
560 Error::PeerMisbehaved(_) => PeerMisbehavedError,
561 Error::UnsupportedNameType => UnsupportedNameType,
562 Error::EncryptError => EncryptError,
563
564 Error::InvalidMessage(e) => map_invalid_message_error(e),
565
566 Error::FailedToGetCurrentTime => FailedToGetCurrentTime,
567 Error::FailedToGetRandomBytes => FailedToGetRandomBytes,
568 Error::HandshakeNotComplete => HandshakeNotComplete,
569 Error::PeerSentOversizedRecord => PeerSentOversizedRecord,
570 Error::NoApplicationProtocol => NoApplicationProtocol,
571 Error::BadMaxFragmentSize => BadMaxFragmentSize,
572
573 Error::InvalidCertificate(e) => map_invalid_certificate_error(e),
574
575 Error::General(_) => General,
576
577 Error::AlertReceived(e) => map_alert_error(e),
578
579 Error::InvalidCertRevocationList(e) => map_crl_error(e),
580
581 Error::InconsistentKeys(InconsistentKeys::KeyMismatch) => InconsistentKeysKeysMismatch,
582 Error::InconsistentKeys(InconsistentKeys::Unknown) => InconsistentKeysUnknown,
583
584 Error::InvalidEncryptedClientHello(err) => map_ech_error(err),
585
586 _ => General,
587 }
588}
589
590pub(crate) fn cert_result_to_error(result: rustls_result) -> Error {
594 use rustls::Error::*;
595 use rustls::OtherError;
596 use rustls_result::*;
597 match result {
598 CertEncodingBad => InvalidCertificate(CertificateError::BadEncoding),
599 CertExpired => InvalidCertificate(CertificateError::Expired),
600 CertNotYetValid => InvalidCertificate(CertificateError::NotValidYet),
601 CertRevoked => InvalidCertificate(CertificateError::Revoked),
602 CertUnhandledCriticalExtension => {
603 InvalidCertificate(CertificateError::UnhandledCriticalExtension)
604 }
605 CertUnknownIssuer => InvalidCertificate(CertificateError::UnknownIssuer),
606 CertBadSignature => InvalidCertificate(CertificateError::BadSignature),
607 CertNotValidForName => InvalidCertificate(CertificateError::NotValidForName),
608 CertInvalidPurpose => InvalidCertificate(CertificateError::InvalidPurpose),
609 CertApplicationVerificationFailure => {
610 InvalidCertificate(CertificateError::ApplicationVerificationFailure)
611 }
612 CertExpiredRevocationList => InvalidCertificate(CertificateError::ExpiredRevocationList),
613 CertOtherError => InvalidCertificate(CertificateError::Other(OtherError(Arc::from(
614 Box::from(""),
615 )))),
616 _ => Error::General("".into()),
617 }
618}
619
620pub(crate) fn map_verifier_builder_error(err: VerifierBuilderError) -> rustls_result {
621 match err {
622 VerifierBuilderError::NoRootAnchors => {
623 rustls_result::ClientCertVerifierBuilderNoRootAnchors
624 }
625 VerifierBuilderError::InvalidCrl(crl_err) => map_crl_error(crl_err),
626 _ => rustls_result::General,
627 }
628}
629
630fn map_alert_error(alert: AlertDescription) -> rustls_result {
631 use rustls_result::*;
632
633 match alert {
634 AlertDescription::CloseNotify => AlertCloseNotify,
635 AlertDescription::UnexpectedMessage => AlertUnexpectedMessage,
636 AlertDescription::BadRecordMac => AlertBadRecordMac,
637 AlertDescription::DecryptionFailed => AlertDecryptionFailed,
638 AlertDescription::RecordOverflow => AlertRecordOverflow,
639 AlertDescription::DecompressionFailure => AlertDecompressionFailure,
640 AlertDescription::HandshakeFailure => AlertHandshakeFailure,
641 AlertDescription::NoCertificate => AlertNoCertificate,
642 AlertDescription::BadCertificate => AlertBadCertificate,
643 AlertDescription::UnsupportedCertificate => AlertUnsupportedCertificate,
644 AlertDescription::CertificateRevoked => AlertCertificateRevoked,
645 AlertDescription::CertificateExpired => AlertCertificateExpired,
646 AlertDescription::CertificateUnknown => AlertCertificateUnknown,
647 AlertDescription::IllegalParameter => AlertIllegalParameter,
648 AlertDescription::UnknownCA => AlertUnknownCA,
649 AlertDescription::AccessDenied => AlertAccessDenied,
650 AlertDescription::DecodeError => AlertDecodeError,
651 AlertDescription::DecryptError => AlertDecryptError,
652 AlertDescription::ExportRestriction => AlertExportRestriction,
653 AlertDescription::ProtocolVersion => AlertProtocolVersion,
654 AlertDescription::InsufficientSecurity => AlertInsufficientSecurity,
655 AlertDescription::InternalError => AlertInternalError,
656 AlertDescription::InappropriateFallback => AlertInappropriateFallback,
657 AlertDescription::UserCanceled => AlertUserCanceled,
658 AlertDescription::NoRenegotiation => AlertNoRenegotiation,
659 AlertDescription::MissingExtension => AlertMissingExtension,
660 AlertDescription::UnsupportedExtension => AlertUnsupportedExtension,
661 AlertDescription::CertificateUnobtainable => AlertCertificateUnobtainable,
662 AlertDescription::UnrecognisedName => AlertUnrecognisedName,
663 AlertDescription::BadCertificateStatusResponse => AlertBadCertificateStatusResponse,
664 AlertDescription::BadCertificateHashValue => AlertBadCertificateHashValue,
665 AlertDescription::UnknownPSKIdentity => AlertUnknownPSKIdentity,
666 AlertDescription::CertificateRequired => AlertCertificateRequired,
667 AlertDescription::NoApplicationProtocol => AlertNoApplicationProtocol,
668 AlertDescription::Unknown(_) => AlertUnknown,
669 _ => AlertUnknown,
670 }
671}
672
673fn map_crl_error(err: CertRevocationListError) -> rustls_result {
674 use rustls_result::*;
675
676 match err {
677 CertRevocationListError::BadSignature => CertRevocationListBadSignature,
678 CertRevocationListError::InvalidCrlNumber => CertRevocationListInvalidCrlNumber,
679 CertRevocationListError::InvalidRevokedCertSerialNumber => {
680 CertRevocationListInvalidRevokedCertSerialNumber
681 }
682 CertRevocationListError::IssuerInvalidForCrl => CertRevocationListIssuerInvalidForCrl,
683 CertRevocationListError::Other(_) => CertRevocationListOtherError,
684 CertRevocationListError::ParseError => CertRevocationListParseError,
685 CertRevocationListError::UnsupportedCrlVersion => CertRevocationListUnsupportedCrlVersion,
686 CertRevocationListError::UnsupportedCriticalExtension => {
687 CertRevocationListUnsupportedCriticalExtension
688 }
689 CertRevocationListError::UnsupportedDeltaCrl => CertRevocationListUnsupportedDeltaCrl,
690 CertRevocationListError::UnsupportedIndirectCrl => CertRevocationListUnsupportedIndirectCrl,
691 CertRevocationListError::UnsupportedRevocationReason => {
692 CertRevocationListUnsupportedRevocationReason
693 }
694 _ => CertRevocationListOtherError,
695 }
696}
697
698fn map_invalid_message_error(err: InvalidMessage) -> rustls_result {
699 use rustls_result::*;
700
701 match err {
702 InvalidMessage::HandshakePayloadTooLarge => MessageHandshakePayloadTooLarge,
703 InvalidMessage::CertificatePayloadTooLarge => MessageCertificatePayloadTooLarge,
704 InvalidMessage::InvalidCcs => MessageInvalidCcs,
705 InvalidMessage::InvalidContentType => MessageInvalidContentType,
706 InvalidMessage::InvalidCertificateStatusType => MessageInvalidCertStatusType,
707 InvalidMessage::InvalidCertRequest => MessageInvalidCertRequest,
708 InvalidMessage::InvalidDhParams => MessageInvalidDhParams,
709 InvalidMessage::InvalidEmptyPayload => MessageInvalidEmptyPayload,
710 InvalidMessage::InvalidKeyUpdate => MessageInvalidKeyUpdate,
711 InvalidMessage::InvalidServerName => MessageInvalidServerName,
712 InvalidMessage::MessageTooLarge => MessageTooLarge,
713 InvalidMessage::MessageTooShort => MessageTooShort,
714 InvalidMessage::MissingData(_) => MessageMissingData,
715 InvalidMessage::MissingKeyExchange => MessageMissingKeyExchange,
716 InvalidMessage::NoSignatureSchemes => MessageNoSignatureSchemes,
717 InvalidMessage::TrailingData(_) => MessageTrailingData,
718 InvalidMessage::UnexpectedMessage(_) => MessageUnexpectedMessage,
719 InvalidMessage::UnknownProtocolVersion => MessageUnknownProtocolVersion,
720 InvalidMessage::UnsupportedCompression => MessageUnsupportedCompression,
721 InvalidMessage::UnsupportedCurveType => MessageUnsupportedCurveType,
722 InvalidMessage::UnsupportedKeyExchangeAlgorithm(_) => MessageUnsupportedCompression,
723 _ => MessageInvalidOther,
724 }
725}
726
727fn map_invalid_certificate_error(err: CertificateError) -> rustls_result {
728 use rustls_result::*;
729
730 match err {
731 CertificateError::BadEncoding => CertEncodingBad,
732 CertificateError::Expired | CertificateError::ExpiredContext { .. } => CertExpired,
733 CertificateError::NotValidYet | CertificateError::NotValidYetContext { .. } => {
734 CertNotYetValid
735 }
736 CertificateError::Revoked => CertRevoked,
737 CertificateError::UnhandledCriticalExtension => CertUnhandledCriticalExtension,
738 CertificateError::UnknownIssuer => CertUnknownIssuer,
739 CertificateError::UnknownRevocationStatus => CertUnknownRevocationStatus,
740 CertificateError::ExpiredRevocationList
741 | CertificateError::ExpiredRevocationListContext { .. } => CertExpiredRevocationList,
742 CertificateError::BadSignature => CertBadSignature,
743 CertificateError::NotValidForName | CertificateError::NotValidForNameContext { .. } => {
744 CertNotValidForName
745 }
746 CertificateError::InvalidPurpose => CertInvalidPurpose,
747 CertificateError::ApplicationVerificationFailure => CertApplicationVerificationFailure,
748 _ => CertOtherError,
749 }
750}
751
752fn map_ech_error(err: EncryptedClientHelloError) -> rustls_result {
753 use rustls_result::*;
754
755 match err {
756 EncryptedClientHelloError::InvalidConfigList => {
757 InvalidEncryptedClientHelloInvalidConfigList
758 }
759 EncryptedClientHelloError::NoCompatibleConfig => {
760 InvalidEncryptedClientHelloNoCompatibleConfig
761 }
762 EncryptedClientHelloError::SniRequired => InvalidEncryptedClientHelloSniRequired,
763 _ => General,
764 }
765}
766
767#[cfg(test)]
768mod tests {
769 use super::*;
770
771 #[test]
772 fn test_rustls_error() {
773 let mut buf = [0 as c_char; 512];
774 let mut n = 0;
775 rustls_result::rustls_error(0, &mut buf as *mut _, buf.len(), &mut n);
776 let output = String::from_utf8(buf[0..n].iter().map(|b| *b as u8).collect()).unwrap();
777 assert_eq!(&output, "a parameter had an invalid value");
778
779 rustls_result::rustls_error(7000, &mut buf as *mut _, buf.len(), &mut n);
780 let output = String::from_utf8(buf[0..n].iter().map(|b| *b as u8).collect()).unwrap();
781 assert_eq!(&output, "OK");
782
783 rustls_result::rustls_error(7101, &mut buf as *mut _, buf.len(), &mut n);
784 let output = String::from_utf8(buf[0..n].iter().map(|b| *b as u8).collect()).unwrap();
785 assert_eq!(&output, "peer sent no certificates");
786 }
787
788 #[test]
789 fn test_rustls_error_into_empty_buffer() {
790 let mut n = 99;
791 rustls_result::rustls_error(0, &mut [] as *mut _, 0, &mut n);
792 assert_eq!(n, 0);
793 }
794
795 #[test]
796 fn test_rustls_result_is_cert_error() {
797 assert!(!rustls_result::rustls_result_is_cert_error(0));
798 assert!(!rustls_result::rustls_result_is_cert_error(7000));
799
800 for id in 7121..=7131 {
802 assert!(rustls_result::rustls_result_is_cert_error(id));
803 }
804 }
805}