Skip to content

Commit 93bf66e

Browse files
committed
Only accept PKCS#8 keys
1 parent 0133734 commit 93bf66e

File tree

4 files changed

+25
-0
lines changed

4 files changed

+25
-0
lines changed

src/imp/openssl.rs

+7
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ pub enum Error {
117117
Normal(ErrorStack),
118118
Ssl(ssl::Error, X509VerifyResult),
119119
EmptyChain,
120+
NotPkcs8,
120121
}
121122

122123
impl error::Error for Error {
@@ -125,6 +126,7 @@ impl error::Error for Error {
125126
Error::Normal(ref e) => error::Error::source(e),
126127
Error::Ssl(ref e, _) => error::Error::source(e),
127128
Error::EmptyChain => None,
129+
Error::NotPkcs8 => None,
128130
}
129131
}
130132
}
@@ -139,6 +141,7 @@ impl fmt::Display for Error {
139141
fmt,
140142
"at least one certificate must be provided to create an identity"
141143
),
144+
Error::NotPkcs8 => write!(fmt, "expected PKCS#8 PEM"),
142145
}
143146
}
144147
}
@@ -171,6 +174,10 @@ impl Identity {
171174
}
172175

173176
pub fn from_pkcs8(buf: &[u8], key: &[u8]) -> Result<Identity, Error> {
177+
if !key.starts_with(b"-----BEGIN PRIVATE KEY-----") {
178+
return Err(Error::NotPkcs8);
179+
}
180+
174181
let pkey = PKey::private_key_from_pem(key)?;
175182
let mut cert_chain = X509::stack_from_pem(buf)?.into_iter();
176183
let cert = cert_chain.next().ok_or(Error::EmptyChain)?;

src/imp/schannel.rs

+4
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,10 @@ impl Identity {
9696
}
9797

9898
pub fn from_pkcs8(pem: &[u8], key: &[u8]) -> Result<Identity, Error> {
99+
if !key.starts_with(b"-----BEGIN PRIVATE KEY-----") {
100+
return Err(io::Error::new(io::ErrorKind::InvalidInput, "not a PKCS#8 key").into());
101+
}
102+
99103
let mut store = Memory::new()?.into_store();
100104
let mut cert_iter = pem::PemBlock::new(pem).into_iter();
101105
let leaf = cert_iter.next().ok_or_else(|| {

src/imp/security_framework.rs

+4
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,10 @@ pub struct Identity {
8585

8686
impl Identity {
8787
pub fn from_pkcs8(pem: &[u8], key: &[u8]) -> Result<Identity, Error> {
88+
if !key.starts_with(b"-----BEGIN PRIVATE KEY-----") {
89+
return Err(Error(base::Error::from(errSecParam)));
90+
}
91+
8892
let dir = TempDir::new().map_err(|_| Error(base::Error::from(errSecIO)))?;
8993
let keychain = keychain::CreateOptions::new()
9094
.password("password")

src/test.rs

+10
Original file line numberDiff line numberDiff line change
@@ -356,6 +356,16 @@ fn import_same_identity_multiple_times() {
356356
let _ = p!(Identity::from_pkcs8(&cert, &key));
357357
}
358358

359+
#[test]
360+
fn from_pkcs8_rejects_rsa_key() {
361+
let keys = test_cert_gen::keys();
362+
let cert = keys.server.cert_and_key.cert.to_pem().into_bytes();
363+
let rsa_key = key_to_pem(keys.server.cert_and_key.key.get_der());
364+
assert!(Identity::from_pkcs8(&cert, rsa_key.as_bytes()).is_err());
365+
let pkcs8_key = rsa_to_pkcs8(&rsa_key);
366+
assert!(Identity::from_pkcs8(&cert, pkcs8_key.as_bytes()).is_ok());
367+
}
368+
359369
#[test]
360370
fn shutdown() {
361371
let keys = test_cert_gen::keys();

0 commit comments

Comments
 (0)