public static bool TestCert(CertificateInfo ci) { bool bRes = true; try { X509Certificate2 cert; if (ci.Password != null) cert = new X509Certificate2(ci.FileName, ci.Password); else cert = new X509Certificate2(ci.FileName); if (!ci.Matches(cert)) bRes = false; // Console.WriteLine("ToString: " + cert.ToString()); // Console.WriteLine("ToString(true): " + cert.ToString(true)); X509Certificate2 certImp = new X509Certificate2(); if (ci.Password != null) certImp.Import(ci.FileName, ci.Password, X509KeyStorageFlags.DefaultKeySet); else certImp.Import(ci.FileName); if (!ci.Matches(certImp)) bRes = false; } catch(Exception e) { bRes = false; Console.WriteLine("Exception is caught:" + Environment.NewLine + e.ToString()); } return bRes; }
public static bool TestCert(CertificateInfo ci) { bool bRes = true; try { X509Certificate2 cert; if (ci.Password != null) cert = new X509Certificate2(ci.FileName, ci.Password); else cert = new X509Certificate2(ci.FileName); string name = cert.FriendlyName; if (ci.Encoding == "PKCS12") { if (name != "My Certificate") { Console.WriteLine("BAD: FriendlyName is not default : \"" + name + "\""); bRes = false; } } else { if (name != String.Empty) { Console.WriteLine("BAD: FriendlyName is not empty for a file loaded cert."); bRes = false; } } // now change the FriendlyName and then read it back and verify cert.FriendlyName = "My Very Nice And Very Friendly Name"; name = cert.FriendlyName; if (name != "My Very Nice And Very Friendly Name") { Console.WriteLine("BAD: failed to set FriendlyName!"); bRes = false; } } catch(Exception e) { bRes = false; Console.WriteLine("Exception is caught:" + Environment.NewLine + e.ToString()); } return bRes; }
public static bool TestCert(CertificateInfo ci) { bool bRes = true; try { X509Certificate2 cert; if (ci.Password != null) cert = new X509Certificate2(ci.FileName, ci.Password); else cert = new X509Certificate2(ci.FileName); // verify that the Arvived is False if (cert.Archived != false) { Console.WriteLine("BAD: Archived property is not false!"); bRes = false; } // now set the archived property to true cert.Archived = true; // this should cover two code paths - PKCS12 certificates are loaded as a store handle vs. DER certs // verify that it reads true if (cert.Archived != true) { Console.WriteLine("BAD: Archived property is not true!"); bRes = false; } // set it to false again and verify cert.Archived = false; if (cert.Archived != false) { Console.WriteLine("BAD: Archived property is not false (2)!"); bRes = false; } } catch(Exception e) { bRes = false; Console.WriteLine("Exception is caught:" + Environment.NewLine + e.ToString()); } return bRes; }
public static bool TestCert(CertificateInfo ci) { bool bRes = true; try { // read a certificate file to a byte array FileStream fs = new FileStream(ci.FileName, FileMode.Open, FileAccess.Read); byte[] certBytes = new byte[(int)fs.Length]; fs.Read(certBytes, 0, certBytes.Length); X509Certificate2 cert; if (ci.Password != null) cert = new X509Certificate2(certBytes, ci.Password); else cert = new X509Certificate2(certBytes); if (!ci.Matches(cert)) bRes = false; // Console.WriteLine("ToString: " + cert.ToString()); // Console.WriteLine("ToString(true): " + cert.ToString(true)); X509Certificate2 certImp = new X509Certificate2(); if (ci.Password != null) certImp.Import(certBytes, ci.Password, X509KeyStorageFlags.DefaultKeySet); else certImp.Import(certBytes); if (!ci.Matches(certImp)) bRes = false; } catch(Exception e) { bRes = false; Console.WriteLine("Exception is caught:" + Environment.NewLine + e.ToString()); } return bRes; }
private void AddToIIS(CertificateInfo certificate) { var host = certificate.HostNames.First(); Site site; if (_tempSiteId == null) { site = _iisClient.ServerManager.Sites.Add(host, "http", string.Format("*:80:{0}", host), "X:\\"); _tempSiteId = site.Id; } else { site = _iisClient.ServerManager.Sites.Where(x => x.Id == _tempSiteId).FirstOrDefault(); } SSLFlags flags = SSLFlags.SNI; if (certificate.Store == null) { flags |= SSLFlags.CentralSSL; } _iisClient.AddOrUpdateBindings(site, host, flags, certificate.Certificate.GetCertHash(), certificate.Store?.Name); _iisClient.Commit(); }
public void Install(IStorePlugin store, CertificateInfo newCertificate, CertificateInfo oldCertificate) { var parameters = _options.ScriptParameters ?? ""; parameters = parameters.Replace("{0}", newCertificate.SubjectName); parameters = parameters.Replace("{1}", _renewal.PfxPassword); parameters = parameters.Replace("{2}", newCertificate.CacheFile?.FullName); parameters = parameters.Replace("{3}", newCertificate.StorePath); parameters = parameters.Replace("{4}", newCertificate.Certificate.FriendlyName); parameters = parameters.Replace("{5}", newCertificate.Certificate.Thumbprint); parameters = parameters.Replace("{6}", newCertificate.CacheFile?.Directory.FullName); parameters = parameters.Replace("{7}", _renewal.Id); parameters = parameters.Replace("{CachePassword}", _renewal.PfxPassword); parameters = parameters.Replace("{CacheFile}", newCertificate.CacheFile?.FullName); parameters = parameters.Replace("{CacheFolder}", newCertificate.CacheFile?.FullName); parameters = parameters.Replace("{CertCommonName}", newCertificate.SubjectName); parameters = parameters.Replace("{CertFriendlyName}", newCertificate.Certificate.FriendlyName); parameters = parameters.Replace("{CertThumbprint}", newCertificate.Certificate.Thumbprint); parameters = parameters.Replace("{StoreType}", _renewal.StorePluginOptions?.Name); parameters = parameters.Replace("{StorePath}", newCertificate.StorePath); parameters = parameters.Replace("{RenewalId}", _renewal.Id); RunScript(_options.Script, parameters); }
public Task Save(CertificateInfo input) { var existing = FindByThumbprint(input.Certificate.Thumbprint); if (existing != null) { _log.Warning("Certificate with thumbprint {thumbprint} is already in the store", input.Certificate.Thumbprint); } else { var certificate = input.Certificate; if (!_settings.Security.PrivateKeyExportable && input.CacheFile != null) { certificate = new X509Certificate2( input.CacheFile.FullName, input.CacheFilePassword, X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet); } _log.Information("Installing certificate in the certificate store"); InstallCertificate(certificate); if (_options.AclFullControl != null) { SetAcl(certificate, _options.AclFullControl); } InstallCertificateChain(input.Chain); } input.StoreInfo.TryAdd( GetType(), new StoreInfo() { Name = CertificateStoreOptions.PluginName, Path = _store.Name }); return(Task.CompletedTask); }
/// <summary> /// Initializes this <see cref="Certificate"/> instance from a handle. /// </summary> /// <param name="handle">The handle from which to initialize the state of the new instance.</param> /// <param name="duplicate"><b>true</b> if the handle should be duplicated, <b>false</b> otherwise.</param> /// <param name="store">The store that owns the certificate.</param> /// <exception cref="ArgumentException"><paramref name="handle"/> is invalid.</exception> private void InitCertificate(IntPtr handle, bool duplicate, CertificateStore store) { if (handle == IntPtr.Zero) throw new ArgumentException("Invalid certificate handle!"); if (duplicate) m_Handle = SspiProvider.CertDuplicateCertificateContext(handle); else m_Handle = handle; m_Context = (CertificateContext)Marshal.PtrToStructure(handle, typeof(CertificateContext)); var certInfo = (OG_CertificateInfo)Marshal.PtrToStructure(m_Context.pCertInfo, typeof(OG_CertificateInfo)); m_CertInfo = new CertificateInfo() { dwVersion = certInfo.dwVersion.ToInt32(), SerialNumbercbData = certInfo.SerialNumbercbData.ToInt32(), SerialNumberpbData = certInfo.SerialNumberpbData, SignatureAlgorithmpszObjId = certInfo.SignatureAlgorithmpszObjId, SignatureAlgorithmParameterscbData = certInfo.SignatureAlgorithmParameterscbData.ToInt32(), SignatureAlgorithmParameterspbData = certInfo.SignatureAlgorithmParameterspbData, IssuercbData = certInfo.IssuercbData.ToInt32(), IssuerpbData = certInfo.IssuerpbData, NotBefore = certInfo.NotBefore, NotAfter = certInfo.NotAfter, SubjectcbData = certInfo.SubjectcbData.ToInt32(), SubjectpbData = certInfo.SubjectpbData, SubjectPublicKeyInfoAlgorithmpszObjId = certInfo.SubjectPublicKeyInfoAlgorithmpszObjId, SubjectPublicKeyInfoAlgorithmParameterscbData = certInfo.SubjectPublicKeyInfoAlgorithmParameterscbData.ToInt32(), SubjectPublicKeyInfoAlgorithmParameterspbData = certInfo.SubjectPublicKeyInfoAlgorithmParameterspbData, SubjectPublicKeyInfoPublicKeycbData = certInfo.SubjectPublicKeyInfoPublicKeycbData.ToInt32(), SubjectPublicKeyInfoPublicKeypbData = certInfo.SubjectPublicKeyInfoPublicKeypbData, SubjectPublicKeyInfoPublicKeycUnusedBits = certInfo.SubjectPublicKeyInfoPublicKeycUnusedBits.ToInt32(), IssuerUniqueIdcbData = certInfo.IssuerUniqueIdcbData.ToInt32(), IssuerUniqueIdpbData = certInfo.IssuerUniqueIdpbData, IssuerUniqueIdcUnusedBits = certInfo.IssuerUniqueIdcUnusedBits.ToInt32(), SubjectUniqueIdcbData = certInfo.SubjectUniqueIdcbData.ToInt32(), SubjectUniqueIdpbData = certInfo.SubjectUniqueIdpbData, SubjectUniqueIdcUnusedBits = certInfo.SubjectUniqueIdcUnusedBits.ToInt32(), cExtension = certInfo.cExtension.ToInt32(), rgExtension = certInfo.rgExtension }; // end changes OG 2011-10-03 if (store == null) { m_Store = null; } else { m_Store = store; } }
public async Task UpdateCertificate(CertificateInfo input, string?site, string?host, string?username, string?password) { const string location = "/nsconfig/ssl"; var pemFilesName = PfxFile.Filename(input.CommonName.Value, ""); site ??= Path.GetFileNameWithoutExtension(pemFilesName); host ??= DefaultNitroHost; username ??= DefaultNitroUsername; password ??= new ProtectedString(DefaultNitroPasswordProtected, _log).Value ?? ""; _log.Verbose($"CitrixAdcClient UpdateCertificate site {site} host {host} creds {username}/{new string('*', password?.Length ?? 1)}"); var apiUrl = GetApiUrl(host); // initialize the HTTP client using var handler = new HttpClientHandler(); using var httpClient = NewHttpClient(handler, username, password); // send the private key and cert chain files var keyFilename = $"{pemFilesName}{PemFiles.KeyFilenameSuffix}{PemFiles.FilenameExtension}"; keyFilename = await PostSystemFile(httpClient, apiUrl, location, site, keyFilename, key : true); if (keyFilename == null) { throw new Exception($"Failed to post {site} key pem."); } var chainFilename = $"{pemFilesName}{PemFiles.ChainFilenameSuffix}{PemFiles.FilenameExtension}"; chainFilename = await PostSystemFile(httpClient, apiUrl, location, site, chainFilename, key : false); if (chainFilename == null) { throw new Exception($"Failed to post {site} chain pem."); } // update the cert var success = await PostSSLCertKey(httpClient, apiUrl, site, chainFilename, keyFilename, _pemFilesPassword); if (!success) { throw new Exception($"Failed to update {site} certificate."); } // verify the cert was successfully updated var verified = await VerifySSLCertKey(httpClient, apiUrl, site, chainFilename, keyFilename); if (!verified) { throw new Exception($"Verification failed for {site} cert update."); } // delete the private key and cert chain files var deletedKey = await DeleteSystemFile(httpClient, apiUrl, location, keyFilename); if (!deletedKey) { _log.Warning("Failed to delete {keyFilename}.", keyFilename); } var deletedCert = await DeleteSystemFile(httpClient, apiUrl, location, chainFilename); if (!deletedCert) { _log.Warning("Failed to delete {chainFilename}.", chainFilename); } }
public ClientSecretAuthenticationMiddleware(RequestDelegate next, IContainerResolve container, ClientSecretAuthenticationOption option) { _next = next ?? throw new ArgumentNullException(nameof(next)); if (null == container) { throw new ArgumentNullException(nameof(container)); } if (null == option) { throw new ArgumentNullException(nameof(option)); } _logger = container.Resolve <ILogger <ClientSecretAuthenticationMiddleware> >(); _option = option; if (null == option.Settings) { _logger.Technical().Warning("No settings have been provided.").Log(); return; } if (option.Settings.Values.ContainsKey(TokenKeys.ProviderIdKey)) { _hasProvider = container.TryResolve(option.Settings.Values[TokenKeys.ProviderIdKey], out _provider); } if (!_hasProvider) { _logger.Technical().Warning("No ClientSecret provider found. Skip ClientSecret capability.").Log(); return; } _hasCertificate = null != option.Certificate && !String.IsNullOrWhiteSpace(option.Certificate.SecretKey) && !String.IsNullOrWhiteSpace(option.Certificate.Name); // check the certificate exists. if (_hasCertificate) { try { var certificateInfo = new CertificateInfo { Name = option.Certificate.Name }; if (Enum.TryParse(option.Certificate.FindType, out X509FindType x509FindType)) { certificateInfo.FindType = x509FindType; } if (Enum.TryParse(option.Certificate.Location, out StoreLocation storeLocation_)) { certificateInfo.Location = storeLocation_; } if (Enum.TryParse(option.Certificate.StoreName, out StoreName storeName_)) { certificateInfo.StoreName = storeName_; } _certificate = Certificate.FindCertificate( certificateInfo.Name, certificateInfo.FindType, certificateInfo.Location, certificateInfo.StoreName); _logger.Technical().System($"Authentication with certificate secret activated.").Log(); } catch (KeyNotFoundException) { _hasCertificate = false; _logger.Technical().Error($"No certificate found with {option.Certificate.FindType} = {option.Certificate.Name} in location = {option.Certificate.Location}.").Log(); } catch (Exception ex) { _logger.Technical().Exception(ex).Log(); } } else { _logger.Technical().System($"No authentication with certificate secret.").Log(); } _activitySource = container.Resolve <IActivitySourceFactory>()?.GetArc4u(); }
public void Save(CertificateInfo input) { _log.Information("Exporting .pem files to {folder}", _path); try { // Determine name var name = input.SubjectName.Replace("*", "_"); // Base certificate var certificateExport = input.Certificate.Export(X509ContentType.Cert); var exportString = _pemService.GetPem("CERTIFICATE", certificateExport); File.WriteAllText(Path.Combine(_path, $"{name}-crt.pem"), exportString); // Rest of the chain var chain = new X509Chain(); chain.Build(input.Certificate); for (var i = 1; i < chain.ChainElements.Count; i++) { var chainCertificate = chain.ChainElements[i].Certificate; // Do not include self-signed certificates, root certificates // are supposed to be known already by the client. if (chainCertificate.Subject != chainCertificate.Issuer) { var chainCertificateExport = chainCertificate.Export(X509ContentType.Cert); exportString += _pemService.GetPem("CERTIFICATE", chainCertificateExport); } } // Save complete chain File.WriteAllText(Path.Combine(_path, $"{name}-chain.pem"), exportString); // Private key var pkPem = ""; var store = new Pkcs12Store(input.CacheFile.OpenRead(), input.CacheFilePassword.ToCharArray()); var alias = store.Aliases.OfType <string>().FirstOrDefault(p => store.IsKeyEntry(p)); var entry = store.GetKey(alias); var key = entry.Key; if (key.IsPrivate) { pkPem = _pemService.GetPem(entry.Key); } if (!string.IsNullOrEmpty(pkPem)) { File.WriteAllText(Path.Combine(_path, $"{name}-key.pem"), pkPem); } else { _log.Warning("No private key found"); } input.StoreInfo.Add(GetType(), new StoreInfo() { Name = PemFilesOptions.PluginName, Path = _path }); } catch (Exception ex) { _log.Error(ex, "Error exporting .pem files to folder"); } }
public void Delete(CertificateInfo input) { _log.Information("Uninstalling certificate from the certificate store"); UninstallCertificate(input.Certificate.Thumbprint); }
static void Main(string[] args) { Trace.EnableConsole(); Trace.EnableFile(); if (!CheckParmeter()) { return; } Trace.Info("check config ok!~"); InitializeVault(); Trace.Info("init vault ok!~"); try { ACMESharpUtils.NewRegistration("", new string[] { "mailto:" + Config.Mail }, true); } catch (Exception ex) { Trace.Error("registration error", ex); return; } Trace.Info("registration ok!~"); try { ACMESharpUtils.NewIdentifier("dns1", Config.Domain); } catch (Exception ex) { Trace.Error("newidentityfier error", ex); return; } Trace.Info("newidentityfier ok!~"); try { AuthorizationState state = ACMESharpUtils.CompleteChallenge("dns1", "http-01", "manual"); if (!CreateChallengeFile(state)) { Trace.Error("create challenge file erro"); return; } } catch (Exception ex) { Trace.Error("complete challenge error", ex); return; } Trace.Info("challege ok"); try { ACMESharpUtils.SubmitChallenge("dns1", "http-01"); } catch (Exception ex) { Trace.Error("submit challenge error", ex); return; } Trace.Info("submit challage ok!~"); Trace.Info("wait LE identifier"); DateTime startT = DateTime.Now; bool result = false; while ((DateTime.Now - startT).TotalSeconds < 300) { AuthorizationState state = null; try { state = ACMESharpUtils.UpdateIdentifier("dns1", "http-01"); } catch (Exception ex) { Trace.Error("update identifier error"); return; } if (state == null) { Trace.Error("update identifier state is null"); return; } var subResultState = state.Challenges.First <ACMESharp.AuthorizeChallenge>(item => item.Type == "http-01"); if (subResultState == null) { SaveState(state); Trace.Error("state is null"); return; } if (subResultState.Status.Equals("valid", StringComparison.CurrentCultureIgnoreCase)) { result = true; break; } else if (subResultState.Status.Equals("invalid", StringComparison.CurrentCultureIgnoreCase)) { SaveState(state); Trace.Error("state is invalid"); return; } else { Trace.Info(DateTime.Now.ToString("HH:mm:ss") + ",status is:" + subResultState.Status); } System.Threading.Thread.Sleep(5000); } if (!result) { Trace.Error("update identifer timeout"); return; } Trace.Info("update identifier ok!~"); try { ACMESharpUtils.NewCertificate("cert1", "dns1", null); } catch (Exception ex) { Trace.Error("new certificate erro", ex); return; } Trace.Info("new certificate is ok!~"); try { ACMESharpUtils.SubmitCertificate("cert1"); } catch (Exception ex) { Trace.Error("submit certificateerro", ex); return; } Trace.Info("submit certificate is ok!~"); try { CertificateInfo info = ACMESharpUtils.UpdateCertificate("cert1"); } catch (Exception ex) { Trace.Error("update certificate erro", ex); return; } Trace.Info("update certificate is ok!~"); if (!GenericCertificate()) { return; } Trace.Info("success!~"); if (Environment.UserInteractive) { Trace.Info("Enter press any key exit!~"); Console.ReadKey(); } }
/// <summary> /// Cleanup after validation /// </summary> /// <param name="renewal"></param> /// <param name="certificateInfo"></param> public abstract void RemoveCertificate(ScheduledRenewal renewal, CertificateInfo certificateInfo);
void IInstallationPlugin.Install(CertificateInfo newCertificateInfo, CertificateInfo oldCertificateInfo) { }
/// <summary> /// Request certificate from the ACME server /// </summary> /// <param name="binding"></param> /// <returns></returns> public CertificateInfo RequestCertificate(Target binding) { // What are we going to get? var identifiers = binding.GetHosts(false); var friendlyName = FriendlyName(binding); var pfxPassword = Properties.Settings.Default.PFXPassword; var pfxFileInfo = new FileInfo(PfxFilePath(binding)); // Try using cached certificate first to avoid rate limiting during // (initial?) deployment troubleshooting. Real certificate requests // will only be done once per day maximum. if (pfxFileInfo.Exists && pfxFileInfo.LastWriteTime > DateTime.Now.AddDays(-1)) { try { var cached = new CertificateInfo() { Certificate = ReadForUse(pfxFileInfo, pfxPassword), PfxFile = pfxFileInfo }; var idn = new IdnMapping(); if (cached.SubjectName == identifiers.First() && cached.HostNames.Count == identifiers.Count && cached.HostNames.All(h => identifiers.Contains(idn.GetAscii(h)))) { if (_options.ForceRenewal) { _log.Warning("Cached certificate available but not used with --forcerenewal. Use 'Renew specific' or 'Renew all' in the main menu to run unscheduled renewals without hitting rate limits."); } else { _log.Warning("Using cached certificate for {friendlyName}. To force issue of a new certificate within 24 hours, delete the .pfx file from the CertificatePath or run with the --forcerenewal switch. Be ware that you might run into rate limits doing so.", friendlyName); return(cached); } } } catch { // File corrupt or invalid password? _log.Warning("Unable to read from certificate cache"); } } using (var cp = CertificateProvider.GetProvider("BouncyCastle")) { // Generate the private key and CSR var rsaPkp = GetRsaKeyParameters(); var rsaKeys = cp.GeneratePrivateKey(rsaPkp); var csr = GetCsr(cp, identifiers, rsaKeys, binding.CommonName); byte[] derRaw; using (var bs = new MemoryStream()) { cp.ExportCsr(csr, EncodingFormat.DER, bs); derRaw = bs.ToArray(); } var derB64U = JwsHelper.Base64UrlEncode(derRaw); // Save request parameters to disk using (var fs = new FileStream(GetPath(binding, "-gen-key.json"), FileMode.Create)) cp.SavePrivateKey(rsaKeys, fs); using (var fs = new FileStream(GetPath(binding, "-key.pem"), FileMode.Create)) cp.ExportPrivateKey(rsaKeys, EncodingFormat.PEM, fs); using (var fs = new FileStream(GetPath(binding, "-gen-csr.json"), FileMode.Create)) cp.SaveCsr(csr, fs); using (var fs = new FileStream(GetPath(binding, "-csr.pem"), FileMode.Create)) cp.ExportCsr(csr, EncodingFormat.PEM, fs); // Request the certificate from the ACME server _log.Information("Requesting certificate {friendlyName}", friendlyName); var certificateRequest = _client.Acme.RequestCertificate(derB64U); if (certificateRequest.StatusCode != HttpStatusCode.Created) { throw new Exception($"Request status {certificateRequest.StatusCode}"); } // Main certicate and issuer certificate Crt certificate; Crt issuerCertificate; // Certificate request was successful, save the certificate itself var crtDerFile = GetPath(binding, $"-crt.der"); _log.Information("Saving certificate to {crtDerFile}", _certificatePath); using (var file = File.Create(crtDerFile)) certificateRequest.SaveCertificate(file); // Save certificate in PEM format too var crtPemFile = GetPath(binding, $"-crt.pem"); using (FileStream source = new FileStream(crtDerFile, FileMode.Open), target = new FileStream(crtPemFile, FileMode.Create)) { certificate = cp.ImportCertificate(EncodingFormat.DER, source); cp.ExportCertificate(certificate, EncodingFormat.PEM, target); } // Get issuer certificate and save in DER and PEM formats issuerCertificate = GetIssuerCertificate(certificateRequest, cp); using (var target = new FileStream(GetPath(binding, "-crt.der", "ca-"), FileMode.Create)) cp.ExportCertificate(issuerCertificate, EncodingFormat.DER, target); var issuerPemFile = GetPath(binding, "-crt.pem", "ca-"); using (var target = new FileStream(issuerPemFile, FileMode.Create)) cp.ExportCertificate(issuerCertificate, EncodingFormat.PEM, target); // Save chain in PEM format using (FileStream intermediate = new FileStream(issuerPemFile, FileMode.Open), certificateStrean = new FileStream(crtPemFile, FileMode.Open), chain = new FileStream(GetPath(binding, "-chain.pem"), FileMode.Create)) { certificateStrean.CopyTo(chain); intermediate.CopyTo(chain); } // All raw data has been saved, now generate the PFX file using (var target = new FileStream(pfxFileInfo.FullName, FileMode.Create)) { try { cp.ExportArchive(rsaKeys, new[] { certificate, issuerCertificate }, ArchiveFormat.PKCS12, target, pfxPassword); } catch (Exception ex) { _log.Error("Error exporting archive {@ex}", ex); } } // Flags used for the internally cached certificate var internalFlags = X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable; // See http://paulstovell.com/blog/x509certificate2 try { // Convert Private Key to different CryptoProvider _log.Verbose("Converting private key..."); var res = new X509Certificate2(pfxFileInfo.FullName, pfxPassword, internalFlags); var privateKey = (RSACryptoServiceProvider)res.PrivateKey; res.PrivateKey = Convert(privateKey); res.FriendlyName = friendlyName; File.WriteAllBytes(pfxFileInfo.FullName, res.Export(X509ContentType.Pfx, pfxPassword)); pfxFileInfo.Refresh(); } catch (Exception ex) { // If we couldn't convert the private key that // means we're left with a pfx generated with the // 'wrong' Crypto provider therefor delete it to // make sure it's retried on the next run. _log.Warning("Error converting private key to Microsoft RSA SChannel Cryptographic Provider, which means it might not be usable for Exchange."); _log.Verbose("{ex}", ex); } // Recreate X509Certificate2 with correct flags for Store/Install return(new CertificateInfo() { Certificate = ReadForUse(pfxFileInfo, pfxPassword), PfxFile = pfxFileInfo }); } }
void IInstallationPlugin.Install(CertificateInfo newCertificate, CertificateInfo oldCertificate) { _iisClient.UpdateFtpSite(_options.SiteId, newCertificate, oldCertificate); }
public void UpdateFtpSite(long FtpSiteId, CertificateInfo newCertificate, CertificateInfo?oldCertificate) { }
public Task Delete(CertificateInfo certificateInfo) => Task.CompletedTask;
public static void TestManagedCertificate(TestContext ctx, X509Certificate2 cert, CertificateInfo expected, bool debug = false) { var subject = cert.SubjectName; if (debug) { ctx.LogMessage("MANAGED SUBJECT: {0}", subject.Name); } if (ctx.Expect(subject, Is.Not.Null, "SubjectName")) { ctx.Expect(subject.Name, Is.EqualTo(expected.ManagedSubjectName), "SubjectName.Name"); } var issuer = cert.IssuerName; if (debug) { ctx.LogMessage("MANAGED ISSUER: {0}", issuer.Name); } if (ctx.Expect(issuer, Is.Not.Null, "IssuerName")) { ctx.Expect(issuer.Name, Is.EqualTo(expected.ManagedIssuerName), "IssuerName.Name"); } ctx.Expect(cert.Subject, Is.EqualTo(expected.ManagedSubjectName), "Subject"); ctx.Expect(cert.Issuer, Is.EqualTo(expected.ManagedIssuerName), "Issue"); ctx.Expect(cert.NotBefore.ToUniversalTime(), Is.EqualTo(expected.NotBefore), "NotBefore"); ctx.Expect(cert.NotAfter.ToUniversalTime(), Is.EqualTo(expected.NotAfter), "NotAfter"); if (!ctx.Expect(cert.GetCertHash(), Is.EqualTo(expected.Hash), "GetCertHash()")) { if (debug) { ctx.LogBufferAsCSharp("hash", "\t\t", cert.GetCertHash()); } } if (!ctx.Expect(cert.GetSerialNumber(), Is.EqualTo(expected.SerialNumberMono), "GetSerialNumber()")) { if (debug) { ctx.LogBufferAsCSharp("serialMono", "\t\t", cert.GetSerialNumber()); } } ctx.Expect(cert.Version, Is.EqualTo(expected.Version), "Version"); if (!ctx.Expect(cert.GetPublicKey(), Is.EqualTo(expected.PublicKeyData), "GetPublicKey()")) { if (debug) { ctx.LogBufferAsCSharp("publicKeyData", "\t\t", cert.GetPublicKey()); } } var signatureAlgorithm = cert.SignatureAlgorithm; if (ctx.Expect(signatureAlgorithm, Is.Not.Null, "SignatureAlgorithm")) { ctx.Expect(signatureAlgorithm.Value, Is.EqualTo(expected.SignatureAlgorithmOid), "SignatureAlgorithm.Value"); } var publicKey = cert.PublicKey; if (ctx.Expect(publicKey, Is.Not.Null, "PublicKey")) { if (ctx.Expect(publicKey.Oid, Is.Not.Null, "PublicKey.Oid")) { ctx.Expect(publicKey.Oid.Value, Is.EqualTo(expected.PublicKeyAlgorithmOid), "PublicKey.Oid.Value"); } var value = publicKey.EncodedKeyValue; if (ctx.Expect(value, Is.Not.Null, "PublicKey.EncodedKeyValue")) { if (ctx.Expect(value.Oid, Is.Not.Null, "PublicKey.Oid")) { ctx.Expect(value.Oid.Value, Is.EqualTo(expected.PublicKeyAlgorithmOid), "PublicKey.Oid.Value"); } ctx.Expect(value.RawData, Is.EqualTo(expected.PublicKeyData), "PublicKey.RawData"); if (debug) { ctx.LogBuffer("PublicKey", value.RawData); } } var publicKeyParams = publicKey.EncodedParameters; if (ctx.Expect(publicKeyParams, Is.Not.Null, "PublicKey.EncodedParameters")) { if (ctx.Expect(publicKeyParams.Oid, Is.Not.Null, "PublicKey.EncodedParameters.Oid")) { ctx.Expect(publicKeyParams.Oid.Value, Is.EqualTo(expected.PublicKeyAlgorithmOid), "PublicKey.EncodedParameters.Oid.Value"); } ctx.Expect(publicKeyParams.RawData, Is.EqualTo(expected.PublicKeyParameters), "PublicKey.EncodedParameters.RawData"); } } }
void IInstallationPlugin.Install(CertificateInfo newCertificate, CertificateInfo oldCertificate) { _iisClient.UpdateFtpSite(_renewal.Binding, SSLFlags.None, newCertificate, oldCertificate); }
/// <summary> /// Make certificate accessible for the world /// </summary> /// <param name="renewal"></param> /// <param name="certificateInfo"></param> public abstract void InstallCertificate(ScheduledRenewal renewal, CertificateInfo certificateInfo);
public CertificateNotFoundException(CertificateInfo certificateInfo) : base(string.Format("No certificate was found with the supplied CertificateInfo parameters:\r\n{0}", GetCertificateInfo(certificateInfo))) { CertificateInfo = certificateInfo; }
public Task Delete(CertificateInfo input) { _log.Information("Uninstalling certificate from the certificate store"); UninstallCertificate(input.Certificate.Thumbprint); return(Task.CompletedTask); }
/// <summary> /// Update/create bindings for all host names in the certificate /// </summary> /// <param name="target"></param> /// <param name="flags"></param> /// <param name="thumbprint"></param> /// <param name="store"></param> public void AddOrUpdateBindings(Target target, SSLFlags flags, CertificateInfo newCertificate, CertificateInfo oldCertificate) { try { var allBindings = WebSites. SelectMany(site => site.Bindings, (site, binding) => new { site, binding }). ToList(); var bindingsUpdated = 0; var found = new List <string>(); var oldThumbprint = oldCertificate?.Certificate?.GetCertHash(); if (oldThumbprint != null) { var siteBindings = allBindings. Where(sb => StructuralComparisons.StructuralEqualityComparer.Equals(sb.binding.CertificateHash, oldThumbprint)). ToList(); // Update all bindings created using the previous certificate foreach (var sb in siteBindings) { try { UpdateBinding(sb.site, sb.binding, flags, newCertificate.Certificate.GetCertHash(), newCertificate.Store?.Name); found.Add(sb.binding.Host); bindingsUpdated += 1; } catch (Exception ex) { _log.Error(ex, "Error updating binding {host}", sb.binding.BindingInformation); throw; } } } // Find all hostnames which are not covered by any of the already updated // bindings yet, because we will want to make sure that those are accessable // in the target site var targetSite = GetWebSite(target.InstallationSiteId ?? target.TargetSiteId ?? -1); IEnumerable <string> todo = target.GetHosts(true); while (todo.Count() > 0) { // Filter by previously matched bindings todo = todo.Where(host => !found.Any(binding => Fits(binding, host, flags) > 0)); if (todo.Count() > 0) { var current = todo.First(); try { var binding = AddOrUpdateBindings( targetSite, current, flags, newCertificate.Certificate.GetCertHash(), newCertificate.Store?.Name, target.SSLPort, true); // Allow a single newly created binding to match with // multiple hostnames on the todo list, e.g. the *.example.com binding // matches with both a.example.com and b.example.com found.Add(binding); bindingsUpdated += 1; } catch (Exception ex) { _log.Error(ex, "Error creating binding {host}: {ex}", current, ex.Message); // Prevent infinite retry loop, we just skip the domain when // an error happens creating a new binding for it. User can // always change/add the bindings manually after all. found.Add(current); } } } if (bindingsUpdated > 0) { _log.Information("Committing {count} {type} binding changes to IIS", bindingsUpdated, "https"); Commit(); _log.Information("IIS will serve the new certificates after the Application Pool IdleTimeout has been reached."); } else { _log.Warning("No bindings have been changed"); } } catch (Exception ex) { _log.Error(ex, "Error installing"); throw; } }
public void Save(CertificateInfo input) { _log.Information("Installing certificate in the certificate store"); input.Store = _store; InstallCertificate(input.Certificate); }
public void UpdateFtpSite(Target target, SSLFlags flags, CertificateInfo newCertificate, CertificateInfo oldCertificate) { var ftpSites = FtpSites.ToList(); var oldThumbprint = oldCertificate?.Certificate?.Thumbprint; var newThumbprint = newCertificate?.Certificate?.Thumbprint; var updated = 0; foreach (var ftpSite in ftpSites) { var sslElement = ftpSite.GetChildElement("ftpServer"). GetChildElement("security"). GetChildElement("ssl"); var currentThumbprint = sslElement.GetAttributeValue("serverCertHash").ToString(); var update = false; if (ftpSite.Id == target.FtpSiteId) { if (string.Equals(currentThumbprint, newThumbprint, StringComparison.CurrentCultureIgnoreCase)) { _log.Information(true, "No updated need for ftp site {name}", ftpSite.Name); } else { update = true; } } else if (string.Equals(currentThumbprint, oldThumbprint, StringComparison.CurrentCultureIgnoreCase)) { update = true; } if (update) { sslElement.SetAttributeValue("serverCertHash", newThumbprint); _log.Information(true, "Updating existing ftp site {name}", ftpSite.Name); updated += 1; } } if (updated > 0) { _log.Information("Committing {count} {type} site changes to IIS", updated, "ftp"); Commit(); } }
public void Delete(CertificateInfo input) { // Not supported }
public Task Delete(CertificateInfo input) => Task.CompletedTask;
/// <summary> /// Initializes this <see cref="Certificate"/> instance from a handle. /// </summary> /// <param name="handle">The handle from which to initialize the state of the new instance.</param> /// <param name="duplicate"><b>true</b> if the handle should be duplicated, <b>false</b> otherwise.</param> /// <param name="store">The store that owns the certificate.</param> /// <exception cref="ArgumentException"><paramref name="handle"/> is invalid.</exception> private void InitCertificate(IntPtr handle, bool duplicate, CertificateStore store) { if (handle == IntPtr.Zero) throw new ArgumentException("Invalid certificate handle!"); if (duplicate) m_Handle = SspiProvider.CertDuplicateCertificateContext(handle); else m_Handle = handle; m_Context = (CertificateContext)Marshal.PtrToStructure(handle, typeof(CertificateContext)); m_CertInfo = (CertificateInfo)Marshal.PtrToStructure(m_Context.pCertInfo, typeof(CertificateInfo)); if (store == null) { m_Store = null; } else { m_Store = store; } }
/// <summary>Saves a certificate.</summary> /// <param name="certificate">The certificate.</param> /// <returns>An asynchronous result.</returns> public Task SaveCertificate(CertificateInfo certificate) { return(this.keyVaultClient.ImportCertificateAsync(this.vaultBaseUrl, certificate.Name, certificate.PfxCertificate.ToString(), certificate.Password)); }
private void CertificateGetInfo() { this.CertificateInfo = DocumentManager.CertificateGetInfo(CertificateInfo); if (this.CertificateInfo != null) { string label = "VerifyCLRok"; DateTime date = (DateTime)Session["VerifyCLR_date"]; //SE LA DATA INSERITA è PRECEDENTE ALLA DATA DI INIZIO VALIDITà if (this.CertificateInfo.RevocationStatus == -500) { label = "VerifyCLRNoConnection"; this.litMessage.Text = "<img src=\"" + Page.ResolveClientUrl("~/Images/Common/messager_error.gif") + "\" alt=\"\" />" + this.GetLabel(label); Session["VerifyCLR_returnValue"] = "VerifyCLRNoConnection"; return; } if (!utils.verificaIntervalloDate(date.ToString(), CertificateInfo.ValidFromDate.ToString())) { label = "VerifyCRLNotValid"; } else { //SE IL CERTIFICATO HA UNA DATA DI REVOCA if (!CertificateInfo.RevocationDate.Equals(DateTime.MinValue)) { if (utils.verificaIntervalloDate(CertificateInfo.RevocationDate.ToString(), date.ToString())) { label = utils.verificaIntervalloDate(CertificateInfo.ValidToDate.ToString(), date.ToString()) ? "VerifyCRLValid" : "VerifyCRLExpired"; } else { label = utils.verificaIntervalloDate(CertificateInfo.ValidToDate.ToString(), date.ToString()) ? "VerifyCRLRevoked" : "VerifyCRLExpired"; } } else { bool valid = utils.verificaIntervalloDate(CertificateInfo.ValidToDate.ToString(), date.ToString()); if (valid && (this.CertificateInfo.RevocationStatus == CODE_CERTIFICATO_SCADUTO || this.CertificateInfo.RevocationStatus == 0)) { label = "VerifyCRLValid"; } else { //è presente un errore.. if (this.CertificateInfo.RevocationStatus != 0) { label = "VerifyCRLInvalid"; } else { label = "VerifyCRLExpired"; } } } } if (label.Equals("VerifyCRLValid")) { this.litMessage.Text = "<img src=\"" + Page.ResolveClientUrl("~/Images/Common/messager_check.gif") + "\" alt=\"\" />" + this.GetLabel(label); } else { string extraInfo = ""; if (!String.IsNullOrEmpty(this.CertificateInfo.RevocationStatusDescription)) { extraInfo = ": " + this.CertificateInfo.RevocationStatusDescription; } this.litMessage.Text = "<img src=\"" + Page.ResolveClientUrl("~/Images/Common/messager_error.gif") + "\" alt=\"\" />" + this.GetLabel(label) + extraInfo; } Session["VerifyCLR_returnValue"] = label; } else { this.litMessage.Text = "<img src=\"" + Page.ResolveClientUrl("~/Images/Common/messager_error.gif") + "\" alt=\"\" />" + this.GetLabel("VerifyCLRko"); Session["VerifyCLR_returnValue"] = "VerifyCLRko"; } }
public Task SaveCertificate(CertificateInfo certificate) { return(Task.CompletedTask); }
public async Task <bool> Install(Target target, IEnumerable <IStorePlugin> store, CertificateInfo newCertificate, CertificateInfo?oldCertificate) { if (_options.Script != null) { var defaultStoreType = store.FirstOrDefault()?.GetType(); var defaultStoreInfo = default(StoreInfo?); if (defaultStoreType != null) { defaultStoreInfo = newCertificate.StoreInfo[defaultStoreType]; } var parameters = ReplaceParameters(_options.ScriptParameters ?? "", defaultStoreInfo, newCertificate, oldCertificate, false); var censoredParameters = ReplaceParameters(_options.ScriptParameters ?? "", defaultStoreInfo, newCertificate, oldCertificate, true); return(await _client.RunScript(_options.Script, parameters, censoredParameters)); } return(false); }
void IInstallationPlugin.Install(IEnumerable <IStorePlugin> stores, CertificateInfo newCertificateInfo, CertificateInfo oldCertificateInfo) { }
public byte[] Get() { try { var path = Path.Combine(Directory.GetCurrentDirectory(), "Certificates\\DevCertRootCA.pfx"); Certificate ca = Certificate.LoadPfx(path, "", KeySetOptions.MachineKeySet); // prepare certificate info var info = new CertificateInfo(); // specify certificate validity range info.EffectiveDate = DateTime.Now.AddDays(-1); info.ExpirationDate = info.EffectiveDate.AddYears(1); // specify certificate subject for a client certificate info.Subject = new DistinguishedName("CN=Sample Certificate"); // specify certificate usage for a client certificate info.Usage = KeyUses.DigitalSignature | KeyUses.KeyEncipherment | KeyUses.DataEncipherment; // specify certificate extended usage for a client certificate info.SetExtendedUsage(ExtendedUsageOids.ClientAuthentication, ExtendedUsageOids.EmailProtection); // sets a unique serial number info.SetSerialNumber(Guid.NewGuid().ToByteArray()); // use SHA-256 signature algorithm info.SignatureHashAlgorithm = HashingAlgorithmId.SHA256; // generate a 2048-bit RSA key for the certificate PrivateKeyInfo privateKey; using (var alg = new AsymmetricKeyAlgorithm()) { alg.GenerateKey(AsymmetricKeyAlgorithmId.RSA, 2048); privateKey = alg.GetPrivateKey(); } // create the certificate signed by the CA certificate PublicKeyInfo publicKey = privateKey.GetPublicKey(); Certificate certificate = CertificateIssuer.Issue(ca, info, publicKey); // associate the private key with the certificate certificate.Associate(privateKey); using (CertificateStore store = new CertificateStore(CertificateStoreName.My, CertificateStoreLocation.LocalMachine)) { store.Add(certificate); } using (CertificateStore store = new CertificateStore(CertificateStoreName.TrustedPeople, CertificateStoreLocation.LocalMachine)) { store.Add(certificate); } var memoryStream = new MemoryStream(); certificate.Save(memoryStream, CertificateFormat.Pfx); return(memoryStream.ToArray()); } catch (Exception ex) { _logger.LogError(ex.Message); throw ex; } }