diff --git a/Notation.Plugin.AzureKeyVault/Certificate/CertificateBundle.cs b/Notation.Plugin.AzureKeyVault/Certificate/CertificateBundle.cs index 68cd234b..a13fe607 100644 --- a/Notation.Plugin.AzureKeyVault/Certificate/CertificateBundle.cs +++ b/Notation.Plugin.AzureKeyVault/Certificate/CertificateBundle.cs @@ -1,4 +1,5 @@ using System.Security.Cryptography.X509Certificates; +using Notation.Plugin.Protocol; namespace Notation.Plugin.AzureKeyVault.Certificate { @@ -14,6 +15,10 @@ public static X509Certificate2Collection Create(string pemFilePath) { var certificates = new X509Certificate2Collection(); certificates.ImportFromPemFile(pemFilePath); + if (certificates.Count == 0) + { + throw new PluginException($"No certificate found in {pemFilePath}"); + } return certificates; } } diff --git a/Notation.Plugin.AzureKeyVault/Command/GenerateSignature.cs b/Notation.Plugin.AzureKeyVault/Command/GenerateSignature.cs index 89ad37a7..82efcd05 100644 --- a/Notation.Plugin.AzureKeyVault/Command/GenerateSignature.cs +++ b/Notation.Plugin.AzureKeyVault/Command/GenerateSignature.cs @@ -43,41 +43,58 @@ public async Task RunAsync() // Obtain the certificate chain X509Certificate2Collection certBundle; X509Certificate2 leafCert; - if (_request.PluginConfig?.TryGetValue("ca_certs", out var certBundlePath) == true) + string? certBundlePath = _request.PluginConfig?.GetValueOrDefault("ca_certs", ""); + + if (_request.PluginConfig?.GetValueOrDefault("self_signed")?.ToLower() == "true") { - // Obtain the certificate bundle from file - // (including the intermediate and root certificates). - certBundle = CertificateBundle.Create(certBundlePath); + if (!string.IsNullOrEmpty(certBundlePath)) + { + throw new PluginException("Self-signed certificate is specified. Please do not specify the `ca_certs` parameter if it is a self-signed certificate."); + } + // Certificate bundle is empty + certBundle = new X509Certificate2Collection(); - // obtain the leaf certificate from Azure Key Vault + // Obtain self-signed leaf certificate from Azure Key Vault leafCert = await _keyVaultClient.GetCertificateAsync(); } else { - // Obtain the certificate chain from Azure Key Vault using - // GetSecret permission. Ensure intermediate and root - // certificates are merged into the Key Vault certificate to - // retrieve the full chain. - // reference: https://learn.microsoft.com//azure/key-vault/certificates/create-certificate-signing-request - X509Certificate2Collection? certificateChain; - try + if (string.IsNullOrEmpty(certBundlePath)) { - certificateChain = await _keyVaultClient.GetCertificateChainAsync(); - } - catch (Azure.RequestFailedException ex) - { - if (ex.Message.Contains("does not have secrets get permission")) + // Obtain the certificate chain from Azure Key Vault using + // GetSecret permission. Ensure intermediate and root + // certificates are merged into the Key Vault certificate to + // retrieve the full chain. + // reference: https://learn.microsoft.com//azure/key-vault/certificates/create-certificate-signing-request + X509Certificate2Collection? certificateChain; + try { - throw new PluginException("The plugin does not have secrets get permission. Please grant the permission to the credential associated with the plugin or specify the file path of the certificate chain bundle through the `ca_certs` parameter in the plugin config."); + certificateChain = await _keyVaultClient.GetCertificateChainAsync(); } - throw; - } + catch (Azure.RequestFailedException ex) + { + if (ex.Message.Contains("does not have secrets get permission")) + { + throw new PluginException("The plugin does not have secrets get permission. Please grant the permission to the credential associated with the plugin or specify the file path of the certificate chain bundle through the `ca_certs` parameter in the plugin config."); + } + throw; + } + + // the certBundle is the certificates start from the second one of certificateChain + certBundle = new X509Certificate2Collection(certificateChain.Skip(1).ToArray()); - // the certBundle is the certificates start from the second one of certificateChain - certBundle = new X509Certificate2Collection(certificateChain.Skip(1).ToArray()); + // the leafCert is the first certificate in the certBundle + leafCert = certificateChain[0]; + } + else + { + // Obtain the certificate bundle from file + // (including the intermediate and root certificates). + certBundle = CertificateBundle.Create(certBundlePath); - // the leafCert is the first certificate in the certBundle - leafCert = certificateChain[0]; + // obtain the leaf certificate from Azure Key Vault + leafCert = await _keyVaultClient.GetCertificateAsync(); + } } // Extract KeySpec from the certificate