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