protected override void ProcessRecord() { using (var vlt = Util.VaultHelper.GetVault(VaultProfile)) { vlt.OpenStorage(); var v = vlt.LoadVault(); if (v.Registrations == null || v.Registrations.Count < 1) { throw new InvalidOperationException("No registrations found"); } var ri = v.Registrations[0]; var r = ri.Registration; if (v.Certificates == null || v.Certificates.Count < 1) { throw new InvalidOperationException("No certificates found"); } var ci = v.Certificates.GetByRef(CertificateRef, throwOnMissing: false); if (ci == null) { throw new Exception("Unable to find a Certificate for the given reference"); } using (var cp = PkiHelper.GetPkiTool( StringHelper.IfNullOrEmpty(PkiTool, v.PkiTool))) { if (!string.IsNullOrEmpty(ci.GenerateDetailsFile)) { // Generate a private key and CSR: // Key: RSA 2048-bit // MD: SHA 256 // CSR: Details pulled from CSR Details JSON file CsrDetails csrDetails; var csrDetailsAsset = vlt.GetAsset(VaultAssetType.CsrDetails, ci.GenerateDetailsFile); using (var s = vlt.LoadAsset(csrDetailsAsset)) { csrDetails = JsonHelper.Load <CsrDetails>(s); } var keyGenFile = $"{ci.Id}-gen-key.json"; var keyPemFile = $"{ci.Id}-key.pem"; var csrGenFile = $"{ci.Id}-gen-csr.json"; var csrPemFile = $"{ci.Id}-csr.pem"; var keyGenAsset = vlt.CreateAsset(VaultAssetType.KeyGen, keyGenFile, getOrCreate: Force); var keyPemAsset = vlt.CreateAsset(VaultAssetType.KeyPem, keyPemFile, isSensitive: true, getOrCreate: Force); var csrGenAsset = vlt.CreateAsset(VaultAssetType.CsrGen, csrGenFile, getOrCreate: Force); var csrPemAsset = vlt.CreateAsset(VaultAssetType.CsrPem, csrPemFile, getOrCreate: Force); var genKeyParams = new RsaPrivateKeyParams(); var genKey = cp.GeneratePrivateKey(genKeyParams); using (var s = vlt.SaveAsset(keyGenAsset)) { cp.SavePrivateKey(genKey, s); } using (var s = vlt.SaveAsset(keyPemAsset)) { cp.ExportPrivateKey(genKey, EncodingFormat.PEM, s); } // TODO: need to surface details of the CSR params up higher var csrParams = new CsrParams { Details = csrDetails }; var genCsr = cp.GenerateCsr(csrParams, genKey, Crt.MessageDigest.SHA256); using (var s = vlt.SaveAsset(csrGenAsset)) { cp.SaveCsr(genCsr, s); } using (var s = vlt.SaveAsset(csrPemAsset)) { cp.ExportCsr(genCsr, EncodingFormat.PEM, s); } ci.KeyPemFile = keyPemFile; ci.CsrPemFile = csrPemFile; } byte[] derRaw; var asset = vlt.GetAsset(VaultAssetType.CsrPem, ci.CsrPemFile); // Convert the stored CSR in PEM format to DER using (var source = vlt.LoadAsset(asset)) { var csr = cp.ImportCsr(EncodingFormat.PEM, source); using (var target = new MemoryStream()) { cp.ExportCsr(csr, EncodingFormat.DER, target); derRaw = target.ToArray(); } } var derB64u = JwsHelper.Base64UrlEncode(derRaw); try { using (var c = ClientHelper.GetClient(v, ri)) { c.Init(); c.GetDirectory(true); ci.CertificateRequest = c.RequestCertificate(derB64u); } } catch (AcmeClient.AcmeWebException ex) { ThrowTerminatingError(PoshHelper.CreateErrorRecord(ex, ci)); return; } if (!string.IsNullOrEmpty(ci.CertificateRequest.CertificateContent)) { var crtDerFile = $"{ci.Id}-crt.der"; var crtPemFile = $"{ci.Id}-crt.pem"; var crtDerBytes = ci.CertificateRequest.GetCertificateContent(); var crtDerAsset = vlt.CreateAsset(VaultAssetType.CrtDer, crtDerFile); var crtPemAsset = vlt.CreateAsset(VaultAssetType.CrtPem, crtPemFile); using (Stream source = new MemoryStream(crtDerBytes), derTarget = vlt.SaveAsset(crtDerAsset), pemTarget = vlt.SaveAsset(crtPemAsset)) { var crt = cp.ImportCertificate(EncodingFormat.DER, source); cp.ExportCertificate(crt, EncodingFormat.DER, derTarget); ci.CrtDerFile = crtDerFile; cp.ExportCertificate(crt, EncodingFormat.PEM, pemTarget); ci.CrtPemFile = crtPemFile; } // Extract a few pieces of info from the issued // cert that we like to have quick access to var x509 = new X509Certificate2(ci.CertificateRequest.GetCertificateContent()); ci.SerialNumber = x509.SerialNumber; ci.Thumbprint = x509.Thumbprint; ci.SignatureAlgorithm = x509.SignatureAlgorithm?.FriendlyName; ci.Signature = x509.GetCertHashString(); } } vlt.SaveVault(v); WriteObject(ci); } }
protected override void ProcessRecord() { using (var vlt = Util.VaultHelper.GetVault(VaultProfile)) { vlt.OpenStorage(); var v = vlt.LoadVault(); if (v.Registrations == null || v.Registrations.Count < 1) { throw new InvalidOperationException("No registrations found"); } var ri = v.Registrations[0]; var r = ri.Registration; if (v.Certificates == null || v.Certificates.Count < 1) { throw new InvalidOperationException("No certificates found"); } var ci = v.Certificates.GetByRef(CertificateRef, throwOnMissing: false); if (ci == null) { throw new Exception("Unable to find a Certificate for the given reference"); } // If we're renaming the Alias, do that // first in case there are any problems if (NewAlias != null) { v.Certificates.Rename(CertificateRef, NewAlias); ci.Alias = NewAlias == "" ? null : NewAlias; } if (!LocalOnly) { if (ci.CertificateRequest == null) { throw new Exception("Certificate has not been submitted yet; cannot update status"); } using (var c = ClientHelper.GetClient(v, ri)) { c.Init(); c.GetDirectory(true); c.RefreshCertificateRequest(ci.CertificateRequest, UseBaseUri); } if ((Repeat || string.IsNullOrEmpty(ci.CrtPemFile)) && !string.IsNullOrEmpty(ci.CertificateRequest.CertificateContent)) { var crtDerFile = $"{ci.Id}-crt.der"; var crtPemFile = $"{ci.Id}-crt.pem"; var crtDerAsset = vlt.ListAssets(crtDerFile, VaultAssetType.CrtDer).FirstOrDefault(); var crtPemAsset = vlt.ListAssets(crtPemFile, VaultAssetType.CrtPem).FirstOrDefault(); if (crtDerAsset == null) { crtDerAsset = vlt.CreateAsset(VaultAssetType.CrtDer, crtDerFile); } if (crtPemAsset == null) { crtPemAsset = vlt.CreateAsset(VaultAssetType.CrtPem, crtPemFile); } using (var cp = PkiHelper.GetPkiTool( StringHelper.IfNullOrEmpty(PkiTool, v.PkiTool))) { var bytes = ci.CertificateRequest.GetCertificateContent(); using (Stream source = new MemoryStream(bytes), derTarget = vlt.SaveAsset(crtDerAsset), pemTarget = vlt.SaveAsset(crtPemAsset)) { var crt = cp.ImportCertificate(EncodingFormat.DER, source); // We're saving the DER format cert "through" // the CP in order to validate its content cp.ExportCertificate(crt, EncodingFormat.DER, derTarget); ci.CrtDerFile = crtDerFile; cp.ExportCertificate(crt, EncodingFormat.PEM, pemTarget); ci.CrtPemFile = crtPemFile; } } var x509 = new X509Certificate2(ci.CertificateRequest.GetCertificateContent()); ci.SerialNumber = x509.SerialNumber; ci.Thumbprint = x509.Thumbprint; ci.SignatureAlgorithm = x509.SignatureAlgorithm?.FriendlyName; ci.Signature = x509.GetCertHashString(); } if (Repeat || string.IsNullOrEmpty(ci.IssuerSerialNumber)) { var linksEnum = ci.CertificateRequest.Links; if (linksEnum != null) { var links = new LinkCollection(linksEnum); var upLink = links.GetFirstOrDefault("up"); if (upLink != null) { // We need to save the ICA certificate to a local // temp file so that we can read it in and store // it properly as a vault asset through a stream var tmp = Path.GetTempFileName(); try { using (var web = new WebClient()) { if (v.Proxy != null) { web.Proxy = v.Proxy.GetWebProxy(); } var uri = new Uri(new Uri(v.BaseUri), upLink.Uri); web.DownloadFile(uri, tmp); } var cacert = new X509Certificate2(tmp); var sernum = cacert.GetSerialNumberString(); var tprint = cacert.Thumbprint; var sigalg = cacert.SignatureAlgorithm?.FriendlyName; var sigval = cacert.GetCertHashString(); if (v.IssuerCertificates == null) { v.IssuerCertificates = new OrderedNameMap <IssuerCertificateInfo>(); } if (Repeat || !v.IssuerCertificates.ContainsKey(sernum)) { var cacertDerFile = $"ca-{sernum}-crt.der"; var cacertPemFile = $"ca-{sernum}-crt.pem"; var issuerDerAsset = vlt.ListAssets(cacertDerFile, VaultAssetType.IssuerDer).FirstOrDefault(); var issuerPemAsset = vlt.ListAssets(cacertPemFile, VaultAssetType.IssuerPem).FirstOrDefault(); if (Repeat || issuerDerAsset == null) { if (issuerDerAsset == null) { issuerDerAsset = vlt.CreateAsset(VaultAssetType.IssuerDer, cacertDerFile); } using (Stream fs = new FileStream(tmp, FileMode.Open), s = vlt.SaveAsset(issuerDerAsset)) { fs.CopyTo(s); } } if (Repeat || issuerPemAsset == null) { if (issuerPemAsset == null) { issuerPemAsset = vlt.CreateAsset(VaultAssetType.IssuerPem, cacertPemFile); } using (var cp = PkiHelper.GetPkiTool( StringHelper.IfNullOrEmpty(PkiTool, v.PkiTool))) { using (Stream source = vlt.LoadAsset(issuerDerAsset), target = vlt.SaveAsset(issuerPemAsset)) { var crt = cp.ImportCertificate(EncodingFormat.DER, source); cp.ExportCertificate(crt, EncodingFormat.PEM, target); } } } v.IssuerCertificates[sernum] = new IssuerCertificateInfo { SerialNumber = sernum, Thumbprint = tprint, SignatureAlgorithm = sigalg, Signature = sigval, CrtDerFile = cacertDerFile, CrtPemFile = cacertPemFile, }; } ci.IssuerSerialNumber = sernum; } finally { if (File.Exists(tmp)) { File.Delete(tmp); } } } } } } ci.Label = StringHelper.IfNullOrEmpty(Label); ci.Memo = StringHelper.IfNullOrEmpty(Memo); vlt.SaveVault(v); WriteObject(ci); } }
protected override void ProcessRecord() { using (var vlt = Util.VaultHelper.GetVault(VaultProfile)) { vlt.OpenStorage(); var v = vlt.LoadVault(); if (v.Certificates == null || v.Certificates.Count < 1) { throw new InvalidOperationException("No certificates found"); } var ci = v.Certificates.GetByRef(CertificateRef, throwOnMissing: false); if (ci == null) { throw new Exception("Unable to find a Certificate for the given reference"); } IssuerCertificateInfo ici = null; if (!string.IsNullOrEmpty(ci.IssuerSerialNumber)) { v.IssuerCertificates.TryGetValue(ci.IssuerSerialNumber, out ici); } PrivateKey pk = null; Crt crt = null; Crt issCrt = null; var keyAsset = vlt.GetAsset(Vault.VaultAssetType.KeyPem, ci.KeyPemFile); var crtAsset = vlt.GetAsset(Vault.VaultAssetType.CrtPem, ci.CrtPemFile); var issCrtAsset = ici != null ? vlt.GetAsset(Vault.VaultAssetType.IssuerPem, ici.CrtPemFile) : null; // Resolve details from inline or profile attributes string installerName = null; IReadOnlyDictionary <string, object> installerParams = null; IReadOnlyDictionary <string, object> cliInstallerParams = null; if (InstallerParameters?.Count > 0) { cliInstallerParams = (IReadOnlyDictionary <string, object> )PoshHelper.Convert <string, object>(InstallerParameters); } if (!string.IsNullOrEmpty(InstallerProfileRef)) { var ppi = v.InstallerProfiles.GetByRef(InstallerProfileRef, throwOnMissing: false); if (ppi == null) { throw new ItemNotFoundException("no Installer profile found for the given reference") .With(nameof(InstallerProfileRef), InstallerProfileRef); } var ppAsset = vlt.GetAsset(Vault.VaultAssetType.InstallerConfigInfo, ppi.Id.ToString()); InstallerProfile ip; using (var s = vlt.LoadAsset(ppAsset)) { ip = JsonHelper.Load <InstallerProfile>(s); } installerName = ip.InstallerProvider; installerParams = ip.InstanceParameters; if (cliInstallerParams != null) { WriteVerbose("Override Installer parameters specified"); if (installerParams?.Count == 0) { WriteVerbose("Profile does not define any parameters, using override parameters only"); installerParams = cliInstallerParams; } else { WriteVerbose("Merging Installer override parameters with profile"); var mergedParams = new Dictionary <string, object>(); foreach (var kv in ip.InstanceParameters) { mergedParams[kv.Key] = kv.Value; } foreach (var kv in cliInstallerParams) { mergedParams[kv.Key] = kv.Value; } installerParams = mergedParams; } } } else { installerName = Installer; installerParams = cliInstallerParams; } using (var pki = PkiHelper.GetPkiTool(v.PkiTool)) { // Load the Private Key // TODO: This is UGLY, but it works for now! using (var s = vlt.LoadAsset(keyAsset)) { try { pk = pki.ImportPrivateKey <RsaPrivateKey>(EncodingFormat.PEM, s); } catch { } } if (pk == null) { using (var s = vlt.LoadAsset(keyAsset)) { try { pk = pki.ImportPrivateKey <EcKeyPair>(EncodingFormat.PEM, s); } catch { } } } if (pk == null) { throw new NotSupportedException("unknown or unsupported private key format"); } // Load the Certificate using (var s = vlt.LoadAsset(crtAsset)) { crt = pki.ImportCertificate(EncodingFormat.PEM, s); } // Load the Issuer Certificate if (issCrtAsset != null) { using (var s = vlt.LoadAsset(issCrtAsset)) { issCrt = pki.ImportCertificate(EncodingFormat.PEM, s); } } // Finally, instantiate and invoke the installer var installerProvider = InstallerExtManager.GetProvider(installerName); using (var installer = installerProvider.GetInstaller(installerParams)) { var chain = new Crt[0]; if (issCrt != null) { chain = new[] { issCrt } } ; installer.Install(pk, crt, chain, pki); } } //try //{ //} //catch (AcmeClient.AcmeWebException ex) //{ // ThrowTerminatingError(PoshHelper.CreateErrorRecord(ex, ci)); // return; //} } } }