Skip to content

Commit

Permalink
microsoft/azure: allow empty certificate chain in PKCS12 file
Browse files Browse the repository at this point in the history
Azure is populating the certs endpoint even when an SSH key is not
provided. The certificate chain in the PKCS12 file is empty in this
case causing afterburn to fail with the current logic. Check if the
certificate chain is empty before retrieving the SSH public key
and warn that a key was not provisioned if it is indeed empty.
  • Loading branch information
marmijo committed May 9, 2024
1 parent f1c93ed commit 2db1a5d
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 2 deletions.
2 changes: 2 additions & 0 deletions docs/release-notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ Major changes:

Minor changes:

- Fix Azure SSH key fetching when no key provisioned.

Packaging changes:


Expand Down
17 changes: 16 additions & 1 deletion src/providers/microsoft/azure/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -412,7 +412,22 @@ impl MetadataProvider for Azure {
bail!("unexpected empty certificates endpoint");
}

let key = self.get_ssh_pubkey(certs_endpoint)?;
// The certs endpoint is being populated even when the user does not supply
// an SSH key when creating a VM. In this case the certificate chain is empty
// causing a failure when trying to access it. Check if the certificate chain
// is empty, meaning that an SSH key hasn't been provided, and only warn
// instead of fail.
let key = match self.get_ssh_pubkey(certs_endpoint) {
Ok(k) => k,
Err(e) => match e.root_cause().to_string().as_ref() {
"detected empty certificate chain" => {
warn!("No SSH keys found in the certificate chain for this instance");
return Ok(vec![]);
}
_ => return Err(e),
},
};

Ok(vec![key])
}

Expand Down
9 changes: 8 additions & 1 deletion src/providers/microsoft/crypto/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,14 @@ pub fn p12_to_ssh_pubkey(p12_der: &[u8]) -> Result<PublicKey> {
// ParsedPKCS12_2 has three parts: a pkey, a main x509 cert, and a list of other
// x509 certs. The list of other x509 certs are called the `certificate chain`
// currently denoted as `ca`; there is only one cert in this `certificate chain`,
// which is the ssh public key.
// which is the ssh public key. The certs endpoint may still be populated even if
// an SSH public key hasn't been provided, which would lead to this code being
// executed. The certificate chain will be empty in this case, so error out and
// handle it further up the stack.
if p12.ca.is_none() {
return Err(anyhow!("detected empty certificate chain"));
}

let ca = p12
.ca
.ok_or_else(|| anyhow!("failed to get chain from pkcs12"))?;
Expand Down

0 comments on commit 2db1a5d

Please sign in to comment.