From 149f66259f13d81a5a76ff2e9679a0174c240737 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sat, 17 Aug 2024 18:36:37 -0400 Subject: [PATCH] Ensure Rsa::check_key doesn't leave errors on the stack --- openssl/src/rsa.rs | 31 ++++++++++++++++++++++++++----- openssl/test/corrupted-rsa.pem | 28 ++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 5 deletions(-) create mode 100644 openssl/test/corrupted-rsa.pem diff --git a/openssl/src/rsa.rs b/openssl/src/rsa.rs index 9ef56942bf..2e6614aed3 100644 --- a/openssl/src/rsa.rs +++ b/openssl/src/rsa.rs @@ -234,14 +234,18 @@ where /// Validates RSA parameters for correctness #[corresponds(RSA_check_key)] - #[allow(clippy::unnecessary_cast)] pub fn check_key(&self) -> Result { unsafe { - let result = ffi::RSA_check_key(self.as_ptr()) as i32; - if result == -1 { - Err(ErrorStack::get()) + let result = ffi::RSA_check_key(self.as_ptr()); + if result != 1 { + let errors = ErrorStack::get(); + if errors.errors().is_empty() { + Ok(false) + } else { + Err(errors) + } } else { - Ok(result == 1) + Ok(true) } } } @@ -849,4 +853,21 @@ mod test { let e = BigNum::from_u32(0x10001).unwrap(); Rsa::generate_with_e(2048, &e).unwrap(); } + + #[test] + fn test_check_key() { + let k = Rsa::private_key_from_pem_passphrase( + include_bytes!("../test/rsa-encrypted.pem"), + b"mypass", + ) + .unwrap(); + assert!(matches!(k.check_key(), Ok(true))); + assert!(ErrorStack::get().errors().is_empty()); + + // BoringSSL simply rejects this key, because its corrupted! + if let Ok(k) = Rsa::private_key_from_pem(include_bytes!("../test/corrupted-rsa.pem")) { + assert!(matches!(k.check_key(), Ok(false) | Err(_))); + assert!(ErrorStack::get().errors().is_empty()); + } + } } diff --git a/openssl/test/corrupted-rsa.pem b/openssl/test/corrupted-rsa.pem new file mode 100644 index 0000000000..fa2cc3b130 --- /dev/null +++ b/openssl/test/corrupted-rsa.pem @@ -0,0 +1,28 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCyiHMQLLOSG6T6 +AYpMTJj9f4WzXQF0+T0Ri/Mk6vcJMQdnLMrlEMIJA/4iCn32zvpQ0raYcuZZoyso +/Svqg7tAeC3aQ/iFopYWfaR+SDMEnpKMl26qwiIxlPcj9J8hAQw/9WA7YneBXq+T +ypONX4EeDn+bsp/mSNSZKYJBmwXevQ9xbnOOxmBrVd5OS07ZwYuQXy8uVsYe4IXX +7/F+BIyULnIlUxRcVRjKp9++PeS53KLJX04H6HeqUiWC8Ntd+DuD3df0a067L38o +sc+CVzwKXqvh75RwlXCR4/B3D9qEqSYmY7lxp9vA3hirWcSJn0xUIbHb7q1hzE0H +rL65mLwnAgMBAAECggEADePYJpKBGBAm35KTcB3ngJWAJp/I92ZVbieNb7peJOzC +btsJIBWT2xVgm2+7NCK5+Tl486xrfTQuLUlhNiTbQof3HUumKr4nCjHqmdlD1YtW +yzG+7kceAkMyOoMThwL+Bn3bPP42CQPVCjJmahyGPvs8H2DK2E+jRr/4KTgxQTki +s/MXmJa4+xhvfF4CmFVj8imkKCyUTFoaqvYevHDMrJ3cohXFONBPv0MT8X/Y0sgw +UVaZ1aw3dbLC2PBpZFotILGxch2rODXgOcer/GBC41aGQTBB8mLPwKb6KMh0xdPd +1E5NwyODA3YJ6W3fGe8WE0MIHoYlOkX+ukf4W4+U0wKBgQDhueBkZwrd1HdhqwhG +QKt1/itCx24Go75G/+5vJUCB4bcdaJP49aH0/H4BiSsKI8r+GVsVJcrKP8h3tgjw +hhuLLPSaWi9TiUsWeDTw0JrAJc7w6hwL1EYbnwcto5mRQdbfugitlkhh17yUmgdj +gczAKLfV3igxslnR67iNOEYrlwKBgQDKejyWNnxhBJoXerpR/hijoXhMaHqV6Z7T +gUy6F0BiJ5CqN+TOTaC17CEnsMmI28o1rWJ6bIKwOUPFXOE9Z5gyxuIJhY9M8n30 +iwm/Ug2oBTFAdZQyyCuCmPiNURnGo+Hhu1EtVwMWLt3Z0L+/DdI6pgPX8mG0NNZm ++pS96Lg9owKBgHOzCslr5638kZSGTh90Vm6McTAxeLv+gjFyTYy6022/fFSenfom +LXWdVhkDbgQshIfqBz23uVIhj2eM7tgaZVPZHydewpNW9B34T2qAAlIrDv99gBKw +I59UzCEgkj5aOQFEId6YAVHlesvQh6kBhymXtWLyFDgk6tUmtdns1krRAoGBAJj0 +pnhDSMpxk4ZRLBdsgGh8PkhaVOCSz2yvrKqXjgeYI+yytKI0ekdzzcgSAOzmPGc4 +R8B74G4HlG6vr2eXrp4NKAxRXOOf/A6UShTBg5d99KrhJ8cE9/l8XadDsNkiTC0e +OECsDqTfWrCExZUqd7neV+D2NWDQ2XaJrXuZJjVJAoGAIGA5ktXIxWIDeXkxo06b +nHeTEmOAgER/5UIikHnoSAnXo5JNZyFxqoylthWuA1fMPQw/UphAeawDwEXVKp1J +NEhLUfVAO/p1RBUsQi8LQVoO9Nql5u5dFjqoCnlRv5tbeAAzZH5magZk7/1rOS5T +Cj7WW2zW+iL20suUmXfCQGU= +-----END RSA PRIVATE KEY-----