Skip to content

Commit bf156f0

Browse files
committed
Don't panic on empty chain
1 parent 483cb8f commit bf156f0

File tree

3 files changed

+26
-11
lines changed

3 files changed

+26
-11
lines changed

src/imp/openssl.rs

+8-7
Original file line numberDiff line numberDiff line change
@@ -116,13 +116,15 @@ fn load_android_root_certs(connector: &mut SslContextBuilder) -> Result<(), Erro
116116
pub enum Error {
117117
Normal(ErrorStack),
118118
Ssl(ssl::Error, X509VerifyResult),
119+
EmptyChain,
119120
}
120121

121122
impl error::Error for Error {
122123
fn source(&self) -> Option<&(dyn error::Error + 'static)> {
123124
match *self {
124125
Error::Normal(ref e) => error::Error::source(e),
125126
Error::Ssl(ref e, _) => error::Error::source(e),
127+
Error::EmptyChain => None,
126128
}
127129
}
128130
}
@@ -133,6 +135,10 @@ impl fmt::Display for Error {
133135
Error::Normal(ref e) => fmt::Display::fmt(e, fmt),
134136
Error::Ssl(ref e, X509VerifyResult::OK) => fmt::Display::fmt(e, fmt),
135137
Error::Ssl(ref e, v) => write!(fmt, "{} ({})", e, v),
138+
Error::EmptyChain => write!(
139+
fmt,
140+
"at least one certificate must be provided to create an identity"
141+
),
136142
}
137143
}
138144
}
@@ -164,14 +170,9 @@ impl Identity {
164170
pub fn from_pkcs8(buf: &[u8], key: &[u8]) -> Result<Identity, Error> {
165171
let pkey = PKey::private_key_from_pem(key)?;
166172
let mut cert_chain = X509::stack_from_pem(buf)?.into_iter();
167-
let cert = cert_chain.next();
173+
let cert = cert_chain.next().ok_or(Error::EmptyChain)?;
168174
let chain = cert_chain.collect();
169-
Ok(Identity {
170-
pkey,
171-
// an identity must have at least one certificate, the leaf cert
172-
cert: cert.expect("at least one certificate must be provided to create an identity"),
173-
chain,
174-
})
175+
Ok(Identity { pkey, cert, chain })
175176
}
176177
}
177178

src/imp/schannel.rs

+12-2
Original file line numberDiff line numberDiff line change
@@ -98,8 +98,18 @@ impl Identity {
9898
pub fn from_pkcs8(pem: &[u8], key: &[u8]) -> Result<Identity, Error> {
9999
let mut store = Memory::new()?.into_store();
100100
let mut cert_iter = pem::PemBlock::new(pem).into_iter();
101-
let leaf = cert_iter.next().expect("at least one certificate must be provided to create an identity");
102-
let cert = CertContext::from_pem(std::str::from_utf8(leaf).map_err(|_| io::Error::new(io::ErrorKind::InvalidInput, "leaf cert contains invalid utf8"))?)?;
101+
let leaf = cert_iter.next().ok_or_else(|| {
102+
io::Error::new(
103+
io::ErrorKind::InvalidInput,
104+
"at least one certificate must be provided to create an identity",
105+
)
106+
})?;
107+
let cert = CertContext::from_pem(std::str::from_utf8(leaf).map_err(|_| {
108+
io::Error::new(
109+
io::ErrorKind::InvalidInput,
110+
"leaf cert contains invalid utf8",
111+
)
112+
})?)?;
103113

104114
let mut options = AcquireOptions::new();
105115
options.container("schannel");

src/imp/security_framework.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -104,10 +104,14 @@ impl Identity {
104104
.keychain(&keychain)
105105
.import(&pem)?;
106106

107-
let ident = SecIdentity::with_certificate(&[keychain], &items.certificates[0])?;
107+
let cert = items
108+
.certificates
109+
.get(0)
110+
.ok_or_else(|| Error(base::Error::from(errSecParam)))?;
111+
let ident = SecIdentity::with_certificate(&[keychain], cert)?;
108112
Ok(Identity {
109113
identity: ident,
110-
chain: items.certificates
114+
chain: items.certificates,
111115
})
112116
}
113117

0 commit comments

Comments
 (0)