X509Certificate2 LoadCertificate() { string thumbprint = ConfigurationManager.AppSettings["nuget:Thumbprint"]; Thumbprint = thumbprint; if (string.IsNullOrWhiteSpace(thumbprint)) { return null; } X509Store certStore = null; try { certStore = new X509Store(StoreName.My, StoreLocation.CurrentUser); certStore.Open(OpenFlags.ReadOnly); X509Certificate2Collection certCollection = certStore.Certificates.Find(X509FindType.FindByThumbprint, thumbprint, false); if (certCollection.Count > 0) { return certCollection[0]; } return null; } finally { if (certStore != null) { certStore.Close(); } } }
/// <summary> /// 获取微信现金红包信息接口 /// 是否需要证书:需要。 /// http://pay.weixin.qq.com/wiki/doc/api/cash_coupon.php?chapter=13_6 /// 使用说明 /// 用于商户对已发放的红包进行查询红包的具体信息,可支持普通红包和裂变包。 /// </summary> /// <param name="nonce_str">(必填) String(32) 随机字符串,不长于32位</param> /// <param name="mch_billno">(必填) String(28) 商户发放红包的商户订单号</param> /// <param name="mch_id">(必填) String(32) 微信支付分配的商户号</param> /// <param name="appid">(必填) String(32) 微信分配的公众账号ID</param> /// <param name="bill_type">(必填) String(32) 订单类型 例子:MCHT ,通过商户订单号获取红包信息。</param> /// <param name="partnerKey">API密钥</param> /// <param name="cert_path">秘钥路径</param> /// <param name="cert_password">秘钥密码</param> /// <returns>返回xml字符串,格式参见:http://pay.weixin.qq.com/wiki/doc/api/cash_coupon.php?chapter=13_6 </returns> public static string GetHbInfo(string nonce_str, string mch_billno, string mch_id, string appid, string bill_type, string partnerKey, string cert_path, string cert_password) { try { var stringADict = new Dictionary<string, string>(); stringADict.Add("nonce_str", nonce_str); stringADict.Add("mch_billno", mch_billno); stringADict.Add("mch_id", mch_id); stringADict.Add("appid", appid); stringADict.Add("bill_type", bill_type); var sign = WxPayAPI.Sign(stringADict, partnerKey);//生成签名字符串 var postdata = PayUtil.GeneralPostdata(stringADict, sign); var url = "https://api.mch.weixin.qq.com/mmpaymkttransfers/gethbinfo"; // 要注意的这是这个编码方式,还有内容的Xml内容的编码方式 Encoding encoding = Encoding.GetEncoding("UTF-8"); byte[] data = encoding.GetBytes(postdata); //ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult); //X509Certificate cer = new X509Certificate(cert_path, cert_password); ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult); X509Certificate cer = new X509Certificate(cert_path, cert_password); #region 该部分是关键,若没有该部分则在IIS下会报 CA证书出错 X509Certificate2 certificate = new X509Certificate2(cert_path, cert_password); X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser); store.Open(OpenFlags.ReadWrite); store.Remove(certificate); //可省略 store.Add(certificate); store.Close(); #endregion HttpWebRequest webrequest = (HttpWebRequest)HttpWebRequest.Create(url); webrequest.ClientCertificates.Add(cer); webrequest.Method = "post"; webrequest.ContentLength = data.Length; Stream outstream = webrequest.GetRequestStream(); outstream.Write(data, 0, data.Length); outstream.Flush(); outstream.Close(); HttpWebResponse webreponse = (HttpWebResponse)webrequest.GetResponse(); Stream instream = webreponse.GetResponseStream(); string resp = string.Empty; using (StreamReader reader = new StreamReader(instream)) { resp = reader.ReadToEnd(); } return resp; } catch (Exception ex) { throw ex; } }
public static void OpenNotExistant() { using (X509Store store = new X509Store(Guid.NewGuid().ToString("N"), StoreLocation.CurrentUser)) { Assert.ThrowsAny<CryptographicException>(() => store.Open(OpenFlags.OpenExistingOnly)); } }
public static void X509CertStoreChain() { X509Store store = new X509Store("My", StoreLocation.LocalMachine); store.Open(OpenFlags.ReadOnly); // can't guarantee there is a certificate in store if (store.Certificates.Count > 0) { X509Chain chain = new X509Chain(); Assert.NotNull(chain.SafeHandle); Assert.Same(chain.SafeHandle, chain.SafeHandle); Assert.True(chain.SafeHandle.IsInvalid); foreach (X509Certificate2 c in store.Certificates) { // can't guarantee success, so no Assert if (chain.Build(c)) { foreach (X509ChainElement k in chain.ChainElements) { Assert.NotNull(k.Certificate.IssuerName.Name); } } } } }
public static void AddReadOnlyThrowsWhenCertificateExists() { using (X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser)) { store.Open(OpenFlags.ReadOnly); X509Certificate2 toAdd = null; // Look through the certificates to find one with no private key to call add on. // (The private key restriction is so that in the event of an "accidental success" // that no potential permissions would be modified) foreach (X509Certificate2 cert in store.Certificates) { if (!cert.HasPrivateKey) { toAdd = cert; break; } } if (toAdd != null) { Assert.ThrowsAny<CryptographicException>(() => store.Add(toAdd)); } } }
public static void OpenMyStore() { using (X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser)) { store.Open(OpenFlags.ReadOnly); } }
private static X509Certificate2 FindX509Certificate(string thumbprint) { List<StoreLocation> locations = new List<StoreLocation> { StoreLocation.CurrentUser, StoreLocation.LocalMachine }; foreach (var location in locations) { X509Store store = new X509Store("My", location); try { store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly); X509Certificate2Collection certificates = store.Certificates.Find( X509FindType.FindByThumbprint, thumbprint, false); if (certificates.Count == 1) { return certificates[0]; } } finally { store.Close(); } } throw new ArgumentException(string.Format("A Certificate with Thumbprint '{0}' could not be located.", thumbprint)); }
static void Main() { try { X509Store store = new X509Store("MY",StoreLocation.CurrentUser); store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly); X509Certificate2Collection collection = X509Certificate2UI.SelectFromCollection( (X509Certificate2Collection)store.Certificates, "Certificate selection", "Select a certificate to obtain the container name from", X509SelectionFlag.SingleSelection); if (collection.Count == 1) { X509Certificate2 x509 = collection[0] ; Console.WriteLine("Subject: {0}", x509.Subject) ; Console.WriteLine("Friendly name: {0}", x509.FriendlyName) ; if (x509.PrivateKey != null) { ICspAsymmetricAlgorithm pkey = x509.PrivateKey as ICspAsymmetricAlgorithm ; Console.WriteLine("Key container name: {0}", pkey.CspKeyContainerInfo.KeyContainerName); } x509.Reset(); } store.Close(); } catch (Exception e) { Console.WriteLine(e.ToString()) ; } }
/// <summary> /// Gets the store certificate matching the thumbprint. The algorithm looks in both the current user and local machine stores and returns the first occurrence. /// </summary> /// <param name="thumbprint">The thumbprint.</param> /// <returns>Client certificate</returns> /// <exception cref="System.ArgumentException">A Certificate with Thumbprint '{0}' could not be located.</exception> private static X509Certificate2 GetStoreCertificate(string thumbprint) { var locations = new List<StoreLocation> { StoreLocation.CurrentUser, StoreLocation.LocalMachine }; foreach(var location in locations) { var store = new X509Store("My", location); try { store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly); X509Certificate2Collection certificates = store.Certificates.Find( X509FindType.FindByThumbprint, thumbprint, false); if(certificates.Count == 1) { return certificates[0]; } } finally { store.Close(); } } throw new ArgumentException(string.Format(Resources.Errors.CertificateNotFound, thumbprint)); }
private static void Main(string[] args) { Task.Run(async () => { Console.WriteLine("Enter PIN: "); string pin = Console.ReadLine(); WebRequestHandler handler = new WebRequestHandler(); handler.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(ValidateServerCertificate); using (HttpClient client = new HttpClient(handler, true)) { client.BaseAddress = new Uri(string.Format(@"https://{0}:{1}", MachineName, RemotePort)); X509Store store = null; try { var response = await client.GetAsync("certs/" + pin); response.EnsureSuccessStatusCode(); byte[] rawCert = await response.Content.ReadAsByteArrayAsync(); X509Certificate2Collection certs = new X509Certificate2Collection(); certs.Import(rawCert, "", X509KeyStorageFlags.Exportable | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.UserKeySet); store = new X509Store(StoreName.My, StoreLocation.CurrentUser); store.Open(OpenFlags.ReadWrite); X509Certificate2Collection oldCerts = new X509Certificate2Collection(); foreach (var cert in certs) { oldCerts.AddRange(store.Certificates.Find(X509FindType.FindBySubjectDistinguishedName, cert.Subject, false)); } store.RemoveRange(certs); store.AddRange(certs); store.Close(); Console.WriteLine("Success"); } catch (HttpRequestException e) { Console.WriteLine("Error communicating with vcremote. Make sure that vcremote is running in secure mode and that a new client cert has been generated."); } finally { if (store != null) { store.Close(); } } } }).Wait(); }
public HttpClientExtensionsFixture() { var store = new X509Store(StoreName.TrustedPeople); store.Open(OpenFlags.ReadOnly); var certName = ConfigurationManager.AppSettings["AuthCertName"]; this.certificate = store.Certificates.Cast<X509Certificate2>() .Single(c => c.Subject.Equals(certName)); }
private static X509Certificate2 GetCertificate(string thumbprint) { X509Store store = new X509Store("My", StoreLocation.LocalMachine); store.Open(OpenFlags.OpenExistingOnly); foreach (X509Certificate2 cert in store.Certificates) { if (cert.Thumbprint == thumbprint) return cert; } return null; }
public static void ReadMyCertificates() { using (X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser)) { store.Open(OpenFlags.ReadOnly); int certCount = store.Certificates.Count; // This assert is just so certCount appears to be used, the test really // is that store.get_Certificates didn't throw. Assert.True(certCount >= 0); } }
static void RemoveCertificatesFromStore(string cert , string password , StoreLocation loc) { //Import the pfx certificates X509Certificate2Collection certificates = new X509Certificate2Collection() ; certificates.Import( cert , password , X509KeyStorageFlags.Exportable | X509KeyStorageFlags.PersistKeySet); //Add the Certificate X509Store store = new X509Store( storeName , loc) ; // , "Cool Store" ) ; store.Open( OpenFlags.ReadWrite ) ; store.RemoveRange( certificates ) ; store.Close() ; }
public static X509Certificate2 GetEligibleClientCertificate() { // Get initial list of client certificates from the MY store. X509Certificate2Collection candidateCerts; using (var myStore = new X509Store(StoreName.My, StoreLocation.CurrentUser)) { myStore.Open(OpenFlags.OpenExistingOnly | OpenFlags.ReadOnly); candidateCerts = myStore.Certificates; } return GetEligibleClientCertificate(candidateCerts); }
public static X509Certificate2 GetCertificate( StoreName name, StoreLocation location, string subjectName ) { X509Store store = new X509Store( name, location ); X509Certificate2Collection certificates = null; store.Open( OpenFlags.ReadOnly ); try { X509Certificate2 result = null; // // Every time we call store.Certificates property, a new collection will be returned. // certificates = store.Certificates; for ( int i = 0; i < certificates.Count; i++ ) { X509Certificate2 cert = certificates[i]; if ( cert.SubjectName.Name.ToLower() == subjectName.ToLower() ) { if ( result != null ) { throw new ApplicationException( string.Format( "There are multiple certificates for subject Name {0}", subjectName ) ); } result = new X509Certificate2( cert ); } } if ( result == null ) { throw new ApplicationException( string.Format( "No certificate was found for subject Name {0}", subjectName ) ); } return result; } finally { if ( certificates != null ) { for ( int i = 0; i < certificates.Count; i++ ) { X509Certificate2 cert = certificates[i]; cert.Reset(); } } store.Close(); } }
public JwtValidationHandlerFixture() { var store = new X509Store(StoreName.TrustedPeople); store.Open(OpenFlags.ReadOnly); var certName = ConfigurationManager.AppSettings["AuthCertName"]; this.certificate = store.Certificates.Cast<X509Certificate2>() .Single(c => c.Subject.Equals(certName)); this.rootRoute = string.Format( "{0}/entities", typeof(JwtValidationHandlerFixtureController).Name.ToLowerInvariant()); }
private static X509Certificate2 GetCertificate(string thumbprint) { X509Store store = new X509Store("My", StoreLocation.LocalMachine); store.Open(OpenFlags.OpenExistingOnly); foreach (X509Certificate2 cert in store.Certificates) { if (String.Equals(cert.Thumbprint, thumbprint, StringComparison.OrdinalIgnoreCase)) { return cert; } } return null; }
static void Main(string[] args) { // // Create the authentication context to be used to acquire tokens. // authContext = new AuthenticationContext(authority); // // Initialize the Certificate Credential to be used by ADAL. // First find the matching certificate in the cert store. // X509Certificate2 cert = null; X509Store store = new X509Store(StoreLocation.CurrentUser); try { store.Open(OpenFlags.ReadOnly); // Place all certificates in an X509Certificate2Collection object. X509Certificate2Collection certCollection = store.Certificates; // Find unexpired certificates. X509Certificate2Collection currentCerts = certCollection.Find(X509FindType.FindByTimeValid, DateTime.Now, false); // From the collection of unexpired certificates, find the ones with the correct name. X509Certificate2Collection signingCert = currentCerts.Find(X509FindType.FindBySubjectDistinguishedName, certName, false); if (signingCert.Count == 0) { // No matching certificate found. return; } // Return the first certificate in the collection, has the right name and is current. cert = signingCert[0]; } finally { store.Close(); } // Then create the certificate credential. certCred = new ClientAssertionCertificate(clientId, cert); // // Call the To Do service 10 times with short delay between calls. // for (int i = 0; i < 10; i++) { Thread.Sleep(3000); PostTodo().Wait(); Thread.Sleep(3000); GetTodo().Wait(); } }
public static X509Certificate2 FindCertificateByThumbprint(string findValue) { X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine); try { store.Open(OpenFlags.ReadOnly); X509Certificate2Collection col = store.Certificates.Find(X509FindType.FindByThumbprint, findValue, false); // Don't validate certs, since the test root isn't installed. if (col == null || col.Count == 0) return null; return col[0]; } finally { store.Close(); } }
public static void AddReadOnlyThrows() { using (X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser)) using (X509Certificate2 cert = new X509Certificate2(TestData.MsCertificate)) { store.Open(OpenFlags.ReadOnly); // Add only throws when it has to do work. If, for some reason, this certificate // is already present in the CurrentUser\My store, we can't really test this // functionality. if (!store.Certificates.Contains(cert)) { Assert.ThrowsAny<CryptographicException>(() => store.Add(cert)); } } }
public static int Main(string[] args) { X509Certificate2 cert = null ; X509Store store = null ; ArrayList al = new ArrayList() ; try { cert = TestCert ; store = new X509Store( StoreName.My , StoreLocation.CurrentUser ) ; store.Open( OpenFlags.ReadWrite ) ; store.Add( cert ) ; Test( X509IncludeOption.ExcludeRoot ) ; Test( X509IncludeOption.WholeChain ) ; Test( X509IncludeOption.EndCertOnly ) ; Test( (X509IncludeOption) 0xFFFF ) ; Test2() ; Test3() ; Test4() ; Test5() ; Test6() ; Test7() ; store.Remove( cert ) ; } catch( Exception e ) { rv = false ; Console.WriteLine( e.ToString() ) ; } finally { store.Close() ; } Console.WriteLine( rv ? "Test passed" : "Test failed" ) ; return rv ? 100 : 101 ; }
//Main method begins here. static void Main(string[] args) { //Test for correct number of arguments. if (args.Length < 1) { Console.WriteLine("Usage: CertInfo <filename>"); return; } try { X509Certificate2 x509 = new X509Certificate2(); //Create X509Certificate2 object from .cer file. byte[] rawData = ReadFile(args[0]); x509.Import(rawData); //Print to console information contained in the certificate. Console.WriteLine(x509.Thumbprint); //Add the certificate to a X509Store. X509Store store = new X509Store(); store.Open(OpenFlags.MaxAllowed); store.Add(x509); store.Close(); } catch (DirectoryNotFoundException) { Console.WriteLine("Error: The directory specified could not be found."); } catch (IOException) { Console.WriteLine("Error: A file in the directory could not be accessed."); } catch (NullReferenceException) { Console.WriteLine("File must be a .cer file. Program does not have access to that type of file."); } }
private static void AddAuthHeader(HttpClient client, string audience = "http://www.enyu.com") { var store = new X509Store(StoreName.My, StoreLocation.LocalMachine); store.Open(OpenFlags.ReadOnly); var signingCert = store.Certificates .Cast<X509Certificate2>() .FirstOrDefault(certificate => certificate.Subject == CertificateName); var tokenDescriptor = new SecurityTokenDescriptor { TokenIssuerName = "DMN", AppliesToAddress = audience, SigningCredentials = new X509SigningCredentials(signingCert) }; var tokenHandler = new JwtSecurityTokenHandler(); var token = tokenHandler.CreateToken(tokenDescriptor); var tokenString = tokenHandler.WriteToken(token); client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", tokenString); }
public HttpResponseMessage Get() { var store = new X509Store(StoreName.My, StoreLocation.LocalMachine); store.Open(OpenFlags.ReadOnly); try { var query = from cert in store.Certificates.Cast<X509Certificate2>() select new { cert.Subject, cert.FriendlyName, cert.Thumbprint }; return Request.CreateResponse(HttpStatusCode.OK, query.ToArray()); } finally { store.Close(); } }
public static HttpClient GetApiClientAsync(string contentType = "application/json") { X509Certificate2 cert = null; X509Store store = null; try { store = new X509Store(StoreName.Root, StoreLocation.LocalMachine); store.Open(OpenFlags.OpenExistingOnly | OpenFlags.ReadOnly); } finally { if (store != null) store.Close(); } var baseUri = new Uri(OdataServiceUri); var clientHandler = new WebRequestHandler(); CredentialCache cc = new CredentialCache(); cc.Add(baseUri, "NTLM", CredentialCache.DefaultNetworkCredentials); clientHandler.Credentials = cc; if (cert != null) clientHandler.ClientCertificates.Add(cert); var client = new HttpClient(clientHandler) { BaseAddress = baseUri }; return client; }
public void ConfigureServices(IServiceCollection services) { var connection = Configuration.GetConnectionString("DefaultConnection"); var useLocalCertStore = Convert.ToBoolean(Configuration["UseLocalCertStore"]); var certificateThumbprint = Configuration["CertificateThumbprint"]; X509Certificate2 cert; if (_webHostEnvironment.IsProduction()) { if (useLocalCertStore) { using (X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine)) { store.Open(OpenFlags.ReadOnly); var certs = store.Certificates.Find(X509FindType.FindByThumbprint, certificateThumbprint, false); cert = certs[0]; store.Close(); } } else { // Azure deployment, will be used if deployed to Azure var vaultConfigSection = Configuration.GetSection("Vault"); var keyVaultService = new KeyVaultCertificateService(vaultConfigSection["Url"], vaultConfigSection["ClientId"], vaultConfigSection["ClientSecret"]); cert = keyVaultService.GetCertificateFromKeyVault(vaultConfigSection["CertificateName"]); } } else { cert = new X509Certificate2(Path.Combine(_webHostEnvironment.ContentRootPath, "damienbodserver.pfx"), ""); } // Important The folderForKeyStore needs to be backed up. // services.AddDataProtection() // .SetApplicationName("ResourceServer") // .PersistKeysToFileSystem(new DirectoryInfo(folderForKeyStore)) // .ProtectKeysWithCertificate(cert); services.AddDataProtection() .SetApplicationName("ResourceServer") .ProtectKeysWithCertificate(cert) .AddKeyManagementOptions(options => options.XmlRepository = new SqlXmlRepository( new DataProtectionDbContext( new DbContextOptionsBuilder <DataProtectionDbContext>().UseSqlite(connection).Options ) ) ); services.AddDbContext <DataEventRecordContext>(options => options.UseSqlite(connection) ); var policy = new Microsoft.AspNetCore.Cors.Infrastructure.CorsPolicy(); policy.Headers.Add("*"); policy.Methods.Add("*"); policy.Origins.Add("*"); policy.SupportsCredentials = true; services.AddCors(x => x.AddPolicy("corsGlobalPolicy", policy)); var guestPolicy = new AuthorizationPolicyBuilder() .RequireAuthenticatedUser() .RequireClaim("scope", "dataEventRecords") .Build(); services.AddAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme) .AddIdentityServerAuthentication(options => { options.Authority = "https://localhost:44318/"; options.ApiName = "dataEventRecordsApi"; options.ApiSecret = "dataEventRecordsSecret"; }); services.AddAuthorization(options => { options.AddPolicy("dataEventRecordsAdmin", policyAdmin => { policyAdmin.RequireClaim("role", "dataEventRecords.admin"); }); options.AddPolicy("dataEventRecordsUser", policyUser => { policyUser.RequireClaim("role", "dataEventRecords.user"); }); options.AddPolicy("dataEventRecords", policyUser => { policyUser.RequireClaim("scope", "dataEventRecordsScope"); }); }); services.AddControllers() .AddNewtonsoftJson() .AddJsonOptions(options => { //options.JsonSerializerOptions.ContractResolver = new DefaultContractResolver(); }); services.AddScoped <IDataEventRecordRepository, DataEventRecordRepository>(); services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new Microsoft.OpenApi.Models.OpenApiInfo { Version = "v1", Title = "API", }); }); }
// This method gets called by the runtime. Use this method to add services to the container. // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940 public void ConfigureServices(IServiceCollection services) { services.Configure <ApiBehaviorOptions>(options => { options.SuppressModelStateInvalidFilter = true; }); var migrationsAssembly = typeof(Startup).GetTypeInfo().Assembly.GetName().Name; var useSqlServer = Convert.ToBoolean(Configuration["BlazorBoilerplate:UseSqlServer"] ?? "false"); var dbConnString = useSqlServer ? Configuration.GetConnectionString("DefaultConnection") : $"Filename={Configuration.GetConnectionString("SqlLiteConnectionFileName")}"; var authAuthority = Configuration["BlazorBoilerplate:IS4ApplicationUrl"].TrimEnd('/'); void DbContextOptionsBuilder(DbContextOptionsBuilder builder) { if (useSqlServer) { builder.UseSqlServer(dbConnString, sql => sql.MigrationsAssembly(migrationsAssembly)); } else if (Convert.ToBoolean(Configuration["BlazorBoilerplate:UsePostgresServer"] ?? "false")) { builder.UseNpgsql(Configuration.GetConnectionString("PostgresConnection"), sql => sql.MigrationsAssembly(migrationsAssembly)); } else { builder.UseSqlite(dbConnString, sql => sql.MigrationsAssembly(migrationsAssembly)); } } services.AddDbContext <ApplicationDbContext>(DbContextOptionsBuilder); services.AddIdentity <ApplicationUser, IdentityRole <Guid> >() .AddRoles <IdentityRole <Guid> >() .AddEntityFrameworkStores <ApplicationDbContext>() .AddDefaultTokenProviders(); services.AddScoped <IUserClaimsPrincipalFactory <ApplicationUser>, AdditionalUserClaimsPrincipalFactory>(); // Adds IdentityServer var identityServerBuilder = services.AddIdentityServer(options => { options.IssuerUri = authAuthority; options.Events.RaiseErrorEvents = true; options.Events.RaiseInformationEvents = true; options.Events.RaiseFailureEvents = true; options.Events.RaiseSuccessEvents = true; }) .AddConfigurationStore(options => { options.ConfigureDbContext = DbContextOptionsBuilder; }) .AddOperationalStore(options => { options.ConfigureDbContext = DbContextOptionsBuilder; // this enables automatic token cleanup. this is optional. options.EnableTokenCleanup = true; options.TokenCleanupInterval = 3600; //In Seconds 1 hour }) .AddAspNetIdentity <ApplicationUser>(); X509Certificate2 cert = null; if (_environment.IsDevelopment()) { // The AddDeveloperSigningCredential extension creates temporary key material for signing tokens. // This might be useful to get started, but needs to be replaced by some persistent key material for production scenarios. // See http://docs.identityserver.io/en/release/topics/crypto.html#refcrypto for more information. // https://stackoverflow.com/questions/42351274/identityserver4-hosting-in-iis //.AddDeveloperSigningCredential(true, @"C:\tempkey.rsa") identityServerBuilder.AddDeveloperSigningCredential(); } else { // Works for IIS, finds cert by the thumbprint in appsettings.json // Make sure Certificate is in the Web Hosting folder && installed to LocalMachine or update settings below var useLocalCertStore = Convert.ToBoolean(Configuration["BlazorBoilerplate:UseLocalCertStore"]); var certificateThumbprint = Configuration["BlazorBoilerplate:CertificateThumbprint"]; if (useLocalCertStore) { using (X509Store store = new X509Store("WebHosting", StoreLocation.LocalMachine)) { store.Open(OpenFlags.ReadOnly); var certs = store.Certificates.Find(X509FindType.FindByThumbprint, certificateThumbprint, false); if (certs.Count > 0) { cert = certs[0]; } else { // import PFX cert = new X509Certificate2(Path.Combine(_environment.ContentRootPath, "AuthSample.pfx"), "Admin123", X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable); // save certificate and private key X509Store storeMy = new X509Store(StoreName.CertificateAuthority, StoreLocation.LocalMachine); storeMy.Open(OpenFlags.ReadWrite); storeMy.Add(cert); } store.Close(); } } else { // Azure deployment, will be used if deployed to Azure - Not tested //var vaultConfigSection = Configuration.GetSection("Vault"); //var keyVaultService = new KeyVaultCertificateService(vaultConfigSection["Url"], vaultConfigSection["ClientId"], vaultConfigSection["ClientSecret"]); ////cert = keyVaultService.GetCertificateFromKeyVault(vaultConfigSection["CertificateName"]); /// I was informed that this will work as a temp solution in Azure cert = new X509Certificate2("AuthSample.pfx", "Admin123", X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable); } identityServerBuilder.AddSigningCredential(cert); } var authBuilder = services.AddAuthentication(options => { options.DefaultScheme = IdentityServerAuthenticationDefaults.AuthenticationScheme; }) .AddIdentityServerAuthentication(options => { options.Authority = authAuthority; options.SupportedTokens = SupportedTokens.Jwt; options.RequireHttpsMetadata = _environment.IsProduction() ? true : false; options.ApiName = IdentityServerConfig.ApiName; }); //https://docs.microsoft.com/en-us/aspnet/core/security/authentication/social/google-logins?view=aspnetcore-3.1 if (Convert.ToBoolean(Configuration["ExternalAuthProviders:Google:Enabled"] ?? "false")) { authBuilder.AddGoogle(options => { options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme; options.ClientId = Configuration["ExternalAuthProviders:Google:ClientId"]; options.ClientSecret = Configuration["ExternalAuthProviders:Google:ClientSecret"]; }); } services.Configure <ApiBehaviorOptions>(options => { options.SuppressModelStateInvalidFilter = true; }); //Add Policies / Claims / Authorization - https://stormpath.com/blog/tutorial-policy-based-authorization-asp-net-core services.AddAuthorization(options => { options.AddPolicy(Policies.IsAdmin, Policies.IsAdminPolicy()); options.AddPolicy(Policies.IsUser, Policies.IsUserPolicy()); options.AddPolicy(Policies.IsReadOnly, Policies.IsReadOnlyPolicy()); options.AddPolicy(Policies.IsMyDomain, Policies.IsMyDomainPolicy()); // valid only on serverside operations }); services.AddTransient <IAuthorizationHandler, DomainRequirementHandler>(); services.Configure <IdentityOptions>(options => { // Password settings options.Password.RequireDigit = false; options.Password.RequiredLength = 6; options.Password.RequireNonAlphanumeric = false; options.Password.RequireUppercase = false; options.Password.RequireLowercase = false; //options.Password.RequiredUniqueChars = 6; // Lockout settings options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(30); options.Lockout.MaxFailedAccessAttempts = 10; options.Lockout.AllowedForNewUsers = true; // Require Confirmed Email User settings if (Convert.ToBoolean(Configuration["BlazorBoilerplate:RequireConfirmedEmail"] ?? "false")) { options.User.RequireUniqueEmail = false; options.SignIn.RequireConfirmedEmail = true; } }); services.Configure <CookiePolicyOptions>(options => { options.MinimumSameSitePolicy = SameSiteMode.None; }); services.ConfigureExternalCookie(options => { // macOS login fix options.Cookie.SameSite = SameSiteMode.None; }); services.ConfigureApplicationCookie(options => { // macOS login fix options.Cookie.SameSite = SameSiteMode.None; options.Cookie.HttpOnly = false; // Suppress redirect on API URLs in ASP.NET Core -> https://stackoverflow.com/a/56384729/54159 options.Events = new CookieAuthenticationEvents() { OnRedirectToAccessDenied = context => { if (context.Request.Path.StartsWithSegments("/api")) { context.Response.StatusCode = (int)(HttpStatusCode.Unauthorized); } return(Task.CompletedTask); }, OnRedirectToLogin = context => { context.Response.StatusCode = 401; return(Task.CompletedTask); } }; }); services.AddControllers().AddNewtonsoftJson(); services.AddSignalR(); services.AddSwaggerDocument(config => { config.PostProcess = document => { document.Info.Version = "v0.2.3"; document.Info.Title = "Blazor Boilerplate"; document.Info.Description = "Blazor Boilerplate / Starter Template using the (ASP.NET Core Hosted) (dotnet new blazorhosted) model. Hosted by an ASP.NET Core server"; }; }); services.AddResponseCompression(opts => { opts.MimeTypes = ResponseCompressionDefaults.MimeTypes.Concat( new[] { "application/octet-stream" }); }); services.AddSingleton <IHttpContextAccessor, HttpContextAccessor>(); services.AddScoped <IUserSession, UserSession>(); services.AddSingleton <IEmailConfiguration>(Configuration.GetSection("EmailConfiguration").Get <EmailConfiguration>()); services.AddTransient <IAccountService, AccountService>(); services.AddTransient <IEmailService, EmailService>(); services.AddTransient <IUserProfileService, UserProfileService>(); services.AddTransient <IApiLogService, ApiLogService>(); services.AddTransient <ITodoService, ToDoService>(); services.AddTransient <IMessageService, MessageService>(); // DB Creation and Seeding services.AddTransient <IDatabaseInitializer, DatabaseInitializer>(); //Automapper to map DTO to Models https://www.c-sharpcorner.com/UploadFile/1492b1/crud-operations-using-automapper-in-mvc-application/ var automapperConfig = new MapperConfiguration(configuration => { configuration.AddProfile(new MappingProfile()); }); var autoMapper = automapperConfig.CreateMapper(); services.AddSingleton(autoMapper); }
/// <summary> /// Configures the services. /// </summary> /// <param name="services">The services.</param> public void ConfigureServices(IServiceCollection services) { services.AddDbContext <IdentityDbContext>(o => { o.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"), sqlOptions => sqlOptions.EnableRetryOnFailure(50, TimeSpan.FromSeconds(30), null)); }); services.AddServicesAndRepositories(); // configures the OpenIdConnect handlers to persist the state parameter into the server-side IDistributedCache. services.AddOidcStateDataFormatterCache(); services.AddControllersWithViews(); IIdentityServerBuilder builder = services.AddIdentityServer(options => { options.Events.RaiseErrorEvents = true; options.Events.RaiseInformationEvents = true; options.Events.RaiseFailureEvents = true; options.Events.RaiseSuccessEvents = true; options.PublicOrigin = Config.Self.PublicOrigin; if (Environment.IsDevelopment()) { options.IssuerUri = Config.Self.IssuerUri; } }); builder.AddInMemoryIdentityResources(IdentityConfig.GetIdentityResources()); builder.AddInMemoryApiResources(IdentityConfig.Apis); builder.AddInMemoryClients(IdentityConfig.Clients(Config)); builder.Services.AddTransient <IProfileService, ProfileService>(); services.AddSingleton(Config); services.AddLocalApiAuthentication(); // sets the authentication schema. services.AddAuthentication(options => { options.DefaultAuthenticateScheme = IdentityServerConstants.DefaultCookieAuthenticationScheme; options.DefaultSignInScheme = IdentityServerConstants.DefaultCookieAuthenticationScheme; options.DefaultChallengeScheme = IdentityServerConstants.DefaultCookieAuthenticationScheme; }) // Adds Fontys Single Sign On authentication. .AddOpenIdConnect("FHICT", "Fontys", options => { options.ClientId = Config.FfhictOIDC.ClientId; options.ClientSecret = Config.FfhictOIDC.ClientSecret; options.Authority = Config.FfhictOIDC.Authority; options.ResponseType = "code"; options.Scope.Clear(); string[] scopes = Config.FfhictOIDC.Scopes.Split(" "); foreach (string scope in scopes) { options.Scope.Add(scope); } // Set this flow to get the refresh token. // options.Scope.Add("offline_access"); options.SaveTokens = true; options.GetClaimsFromUserInfoEndpoint = true; // This sets the redirect uri, this is needed because the blackbox implementation does not implement fontys SSO. options.Events.OnRedirectToIdentityProvider = async n => { n.ProtocolMessage.RedirectUri = Config.FfhictOIDC.RedirectUri; await Task.FromResult(0); }; } // Add jwt validation this is so that the DGS can authenticate. ) .AddJwtBearer(o => { o.SaveToken = true; o.Authority = Config.Self.JwtAuthority; o.RequireHttpsMetadata = false; o.TokenValidationParameters = new TokenValidationParameters { ValidateActor = false, ValidateAudience = false, NameClaimType = "name", RoleClaimType = "http://schemas.microsoft.com/ws/2008/06/identity/claims/role" }; }) .AddCookie(); if (Environment.IsDevelopment()) { builder.AddDeveloperSigningCredential(); } else { X509Store certStore = new X509Store(StoreName.My, StoreLocation.CurrentUser); certStore.Open(OpenFlags.ReadOnly); X509Certificate2Collection certCollection = certStore.Certificates.Find(X509FindType.FindByIssuerName, "Let's Encrypt Authority X3", false); if (certCollection.Count > 0) { X509Certificate2 certificate = certCollection[0]; builder.AddSigningCredential(certificate); } } // TODO tighten cors services.AddCors(options => { options.AddPolicy("dex-api", policy => { policy.AllowAnyOrigin() .AllowAnyHeader() .AllowAnyMethod(); }); }); }
public static void TryInstallingCertificate_PromptForKey(string CertificateFilename, bool ShowPrompt = true) { try { if (!String.IsNullOrEmpty(CertificateFilename) || ShowOpenFileDialog(CertificatesFilter, "Choose a code signing certificate to import", "", "", ref ChoosingFilesToInstallDirectory, out CertificateFilename)) { if (Environment.OSVersion.Platform == PlatformID.MacOSX || Environment.OSVersion.Platform == PlatformID.Unix) { // run certtool y to get the currently installed certificates CertToolData = ""; Process CertTool = new Process(); CertTool.StartInfo.FileName = "/usr/bin/security"; CertTool.StartInfo.UseShellExecute = false; CertTool.StartInfo.Arguments = "import \"" + CertificateFilename + "\" -k login.keychain"; CertTool.StartInfo.RedirectStandardOutput = true; CertTool.OutputDataReceived += new DataReceivedEventHandler(OutputReceivedCertToolProcessCall); CertTool.Start(); CertTool.BeginOutputReadLine(); CertTool.WaitForExit(); if (CertTool.ExitCode != 0) { // todo: provide some feedback that it failed } Console.Write(CertToolData); } else { // Load the certificate string CertificatePassword = ""; X509Certificate2 Cert = null; try { Cert = new X509Certificate2(CertificateFilename, CertificatePassword, X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable | X509KeyStorageFlags.MachineKeySet); } catch (System.Security.Cryptography.CryptographicException ex) { // Try once with a password if (PasswordDialog.RequestPassword(out CertificatePassword)) { Cert = new X509Certificate2(CertificateFilename, CertificatePassword, X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable | X509KeyStorageFlags.MachineKeySet); } else { // User cancelled dialog, rethrow throw ex; } } // If the certificate doesn't have a private key pair, ask the user to provide one if (!Cert.HasPrivateKey) { string ErrorMsg = "Certificate does not include a private key and cannot be used to code sign"; // Prompt for a key pair if (MessageBox(new IntPtr(0), "Next, please choose the key pair that you made when generating the certificate request.", Config.AppDisplayName, 0x00000000 | 0x00000040 | 0x00001000 | 0x00010000) == 1) { string KeyFilename; if (ShowOpenFileDialog(KeysFilter, "Choose the key pair that belongs with the signing certificate", "", "", ref ChoosingFilesToInstallDirectory, out KeyFilename)) { Cert = CryptoAdapter.CombineKeyAndCert(CertificateFilename, KeyFilename); if (Cert.HasPrivateKey) { ErrorMsg = null; } } } if (ErrorMsg != null) { throw new Exception(ErrorMsg); } } // Add the certificate to the store X509Store Store = new X509Store(); Store.Open(OpenFlags.ReadWrite); Store.Add(Cert); Store.Close(); } } } catch (Exception ex) { string ErrorMsg = String.Format("Failed to load or install certificate due to an error: '{0}'", ex.Message); Program.Error(ErrorMsg); System.Threading.Thread.Sleep(500); MessageBox(new IntPtr(0), ErrorMsg, Config.AppDisplayName, 0x00000000 | 0x00000010 | 0x00001000 | 0x00010000); } }
public static void BuildChain_MicrosoftDotCom_WithRootCertInUserAndSystemRootCertStores() { // Verifies that when the same root cert is placed in both a user and machine root certificate store, // any certs chain building to that root cert will build correctly // // We use a copy of the microsoft.com SSL certs and root certs to validate that the chain can build // successfully bool shouldInstallCertToUserStore = true; bool installedCertToUserStore = false; using (var microsoftDotCom = new X509Certificate2(TestData.MicrosoftDotComSslCertBytes)) using (var microsoftDotComRoot = new X509Certificate2(TestData.MicrosoftDotComRootBytes)) { // Check that microsoft.com's root certificate IS installed in the machine root store as a sanity step using (var machineRootStore = new X509Store(StoreName.Root, StoreLocation.LocalMachine)) { machineRootStore.Open(OpenFlags.ReadOnly); bool foundCert = false; foreach (var machineCert in machineRootStore.Certificates) { if (machineCert.Equals(microsoftDotComRoot)) { foundCert = true; } machineCert.Dispose(); } Assert.True(foundCert, string.Format("Did not find expected certificate with thumbprint '{0}' in the machine root store", microsoftDotComRoot.Thumbprint)); } // Concievably at this point there could still be something wrong and we still don't chain build correctly - if that's // the case, then there's likely something wrong with the machine. Validating that happy path is out of scope // of this particular test. // Check that microsoft.com's root certificate is NOT installed on in the user cert store as a sanity step // We won't try to install the microsoft.com root cert into the user root store if it's already there using (var userRootStore = new X509Store(StoreName.Root, StoreLocation.CurrentUser)) { userRootStore.Open(OpenFlags.ReadOnly); foreach (var userCert in userRootStore.Certificates) { bool foundCert = false; if (userCert.Equals(microsoftDotComRoot)) { foundCert = true; } userCert.Dispose(); if (foundCert) { shouldInstallCertToUserStore = false; } } } using (var userRootStore = new X509Store(StoreName.Root, StoreLocation.CurrentUser)) using (var chainHolder = new ChainHolder()) { try { if (shouldInstallCertToUserStore) { try { userRootStore.Open(OpenFlags.ReadWrite); } catch (CryptographicException) { return; } userRootStore.Add(microsoftDotComRoot); // throws CryptographicException installedCertToUserStore = true; } X509Chain chainValidator = chainHolder.Chain; chainValidator.ChainPolicy.VerificationTime = new DateTime(2015, 10, 15, 12, 01, 01, DateTimeKind.Local); chainValidator.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck; bool chainBuildResult = chainValidator.Build(microsoftDotCom); StringBuilder builder = new StringBuilder(); foreach (var status in chainValidator.ChainStatus) { builder.AppendFormat("{0} {1}{2}", status.Status, status.StatusInformation, Environment.NewLine); } Assert.True(chainBuildResult, string.Format("Certificate chain build failed. ChainStatus is:{0}{1}", Environment.NewLine, builder.ToString())); } finally { if (installedCertToUserStore) { userRootStore.Remove(microsoftDotComRoot); } } } } }
/// <summary> /// Validate Certificate /// </summary> /// <param name="request">HttpRequestMessage value</param> /// <returns>HttpResponseMessage object</returns> private HttpResponseMessage ValidateCertificate(HttpRequestMessage request) { IEnumerable <string> thumbPrints; if (!request.Headers.TryGetValues("Thumbprint", out thumbPrints) || thumbPrints == null || (thumbPrints != null && thumbPrints.Count() == 0)) { return(request.CreateResponse(HttpStatusCode.NotAcceptable, new Message() { Content = "Thumbprint request header is not available !" })); } try { List <StoreLocation> locations = new List <StoreLocation> // Certificate location indicators { StoreLocation.CurrentUser, StoreLocation.LocalMachine }; bool? verified = null; // A flag used to check Certificate validation List <string> thumbPrintCollection = new List <string>(); if (thumbPrints.FirstOrDefault().Contains(',')) // Has many thumbprints { thumbPrintCollection.AddRange(thumbPrints.FirstOrDefault().Split(',')); } else { thumbPrintCollection.Add(thumbPrints.FirstOrDefault()); } OpenFlags openFlags = OpenFlags.OpenExistingOnly | OpenFlags.ReadOnly; foreach (var thumbPrint in thumbPrintCollection) { foreach (var location in locations) { X509Store store = new X509Store(StoreName.Root, location); // Look the certificates under Trusted Root Certification Authorities(CA) try { store.Open(openFlags); X509Certificate2Collection certificates = store.Certificates.Find(X509FindType.FindByThumbprint, thumbPrint, validOnly: true);// Make sure it's valid only if (certificates != null && certificates.Count > 0) { // Check if the CN(Host + Domain Name) contains the request host foreach (var certificate in certificates) { if (!string.IsNullOrWhiteSpace(certificate.Subject) && !string.IsNullOrWhiteSpace(request.RequestUri.Host) && certificate.Subject.ToLower().Contains(request.RequestUri.Host.ToLower())) { return(request.CreateResponse(HttpStatusCode.OK)); } } } else { certificates = store.Certificates.Find(X509FindType.FindByThumbprint, thumbPrint, validOnly: false); if (certificates != null && certificates.Count > 0) { verified = false; } } } finally { store.Close(); } } } if (verified.HasValue && !verified.Value) { return(request.CreateResponse(HttpStatusCode.Unauthorized, new Message() { Content = "Certificate is available but not valid !" })); } else { return(request.CreateResponse(HttpStatusCode.NotFound, new Message() { Content = "Certificate is not available !" })); } } catch (Exception exception) { // Log error return(request.CreateResponse(HttpStatusCode.BadRequest, new Message() { Content = string.Concat("Exception happens while processing certificate !\n", exception) })); } }
// This method gets called by the runtime. Use this method to add services to the container. // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940 public void ConfigureServices(IServiceCollection services) { services.AddLocalization() .Configure <RequestLocalizationOptions>(options => { options.DefaultRequestCulture = new RequestCulture(Localization.Settings.SupportedCultures[0]); options.AddSupportedCultures(Localization.Settings.SupportedCultures); options.AddSupportedUICultures(Localization.Settings.SupportedCultures); }); var dataProtectionBuilder = services.AddDataProtection().SetApplicationName(projectName); services.RegisterStorage(Configuration); services.Configure <ApiBehaviorOptions>(options => { options.SuppressModelStateInvalidFilter = true; }); services.AddIdentity <ApplicationUser, IdentityRole <Guid> >() .AddRoles <IdentityRole <Guid> >() .AddEntityFrameworkStores <ApplicationDbContext>() .AddDefaultTokenProviders() .AddErrorDescriber <LocalizedIdentityErrorDescriber>(); services.AddScoped <IUserClaimsPrincipalFactory <ApplicationUser>, AdditionalUserClaimsPrincipalFactory>(); var authAuthority = Configuration[$"{projectName}:IS4ApplicationUrl"].TrimEnd('/'); // Adds IdentityServer https://identityserver4.readthedocs.io/en/latest/reference/options.html var identityServerBuilder = services.AddIdentityServer(options => { options.IssuerUri = authAuthority; options.Events.RaiseErrorEvents = true; options.Events.RaiseInformationEvents = true; options.Events.RaiseFailureEvents = true; options.Events.RaiseSuccessEvents = true; options.UserInteraction.ErrorUrl = "/identityserver/error"; }) .AddIdentityServerStores(Configuration) .AddAspNetIdentity <ApplicationUser>(); //https://identityserver4.readthedocs.io/en/latest/reference/aspnet_identity.html X509Certificate2 cert = null; var keysFolder = Path.Combine(_environment.ContentRootPath, "Keys"); if (_environment.IsDevelopment()) { // The AddDeveloperSigningCredential extension creates temporary key material tempkey.jwk for signing tokens. // This might be useful to get started, but needs to be replaced by some persistent key material for production scenarios. // See http://docs.identityserver.io/en/release/topics/crypto.html#refcrypto for more information. // https://stackoverflow.com/questions/42351274/identityserver4-hosting-in-iis identityServerBuilder.AddDeveloperSigningCredential(); dataProtectionBuilder.PersistKeysToFileSystem(new DirectoryInfo(keysFolder)); } else { // running on azure // please make sure to replace your vault URI and your certificate name in appsettings.json! if (Convert.ToBoolean(Configuration["HostingOnAzure:RunsOnAzure"]) == true) { // if we use a key vault if (Convert.ToBoolean(Configuration["HostingOnAzure:AzurekeyVault:UsingKeyVault"]) == true) { //https://docs.microsoft.com/en-us/aspnet/core/security/data-protection/configuration/overview dataProtectionBuilder.PersistKeysToAzureBlobStorage(new Uri("<blobUriWithSasToken>")) .ProtectKeysWithAzureKeyVault("<keyIdentifier>", "<clientId>", "<clientSecret>"); // if managed app identity is used if (Convert.ToBoolean(Configuration["HostingOnAzure:AzurekeyVault:UseManagedAppIdentity"]) == true) { try { AzureServiceTokenProvider azureServiceTokenProvider = new AzureServiceTokenProvider(); var keyVaultClient = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(azureServiceTokenProvider.KeyVaultTokenCallback)); var certificateBundle = keyVaultClient.GetSecretAsync(Configuration["HostingOnAzure:AzureKeyVault:VaultURI"], Configuration["HostingOnAzure:AzurekeyVault:CertificateName"]).GetAwaiter().GetResult(); var certificate = Convert.FromBase64String(certificateBundle.Value); cert = new X509Certificate2(certificate, (string)null, X509KeyStorageFlags.MachineKeySet); } catch (Exception ex) { throw ex; } } } else // if app id and app secret are used { throw new NotImplementedException(); } } else { dataProtectionBuilder.PersistKeysToFileSystem(new DirectoryInfo(keysFolder)); } //TODO this implementation does not consider certificate expiration if (Convert.ToBoolean(Configuration[$"{projectName}:UseLocalCertStore"]) == true) { var certificateThumbprint = Configuration[$"{projectName}:CertificateThumbprint"]; using (X509Store store = new X509Store("WebHosting", StoreLocation.LocalMachine)) { store.Open(OpenFlags.ReadOnly); var certs = store.Certificates.Find(X509FindType.FindByThumbprint, certificateThumbprint, false); if (certs.Count > 0) { cert = certs[0]; } else { var certPath = Path.Combine(_environment.ContentRootPath, "AuthSample.pfx"); if (File.Exists(certPath)) { cert = new X509Certificate2(certPath, "Admin123", X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable); } } store.Close(); } } // pass the resulting certificate to Identity Server if (cert != null) { identityServerBuilder.AddSigningCredential(cert); Log.Logger.Information($"Added certificate {cert.Subject} to Identity Server"); } else { Log.Logger.Debug("Trying to use WebHosting Certificate for Identity Server"); identityServerBuilder.AddWebHostingCertificate(); } } services.AddProtectedBrowserStorage(); var authBuilder = services.AddAuthentication(options => { options.DefaultScheme = IdentityServerAuthenticationDefaults.AuthenticationScheme; }) .AddIdentityServerAuthentication(options => { options.Authority = authAuthority; options.SupportedTokens = SupportedTokens.Jwt; options.RequireHttpsMetadata = _environment.IsProduction() ? true : false; options.ApiName = IdentityServerConfig.LocalApiName; }); #region ExternalAuthProviders //https://github.com/dotnet/aspnetcore/blob/master/src/Security/Authentication/samples/SocialSample/Startup.cs //https://docs.microsoft.com/en-us/aspnet/core/security/authentication/social/google-logins if (Convert.ToBoolean(Configuration["ExternalAuthProviders:Google:Enabled"] ?? "false")) { authBuilder.AddGoogle(options => { options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme; options.ClientId = Configuration["ExternalAuthProviders:Google:ClientId"]; options.ClientSecret = Configuration["ExternalAuthProviders:Google:ClientSecret"]; options.AuthorizationEndpoint += "?prompt=consent"; // Hack so we always get a refresh token, it only comes on the first authorization response options.AccessType = "offline"; options.SaveTokens = true; options.Events = new OAuthEvents() { OnRemoteFailure = HandleOnRemoteFailure }; options.ClaimActions.MapJsonSubKey("urn:google:image", "image", "url"); options.ClaimActions.Remove(ClaimTypes.GivenName); }); } if (Convert.ToBoolean(Configuration["ExternalAuthProviders:Facebook:Enabled"] ?? "false")) { // You must first create an app with Facebook and add its ID and Secret to your user-secrets. // https://developers.facebook.com/apps/ // https://developers.facebook.com/docs/facebook-login/manually-build-a-login-flow#login authBuilder.AddFacebook(options => { options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme; options.AppId = Configuration["ExternalAuthProviders:Facebook:AppId"]; options.AppSecret = Configuration["ExternalAuthProviders:Facebook:AppSecret"]; options.Scope.Add("email"); options.Fields.Add("name"); options.Fields.Add("email"); options.SaveTokens = true; options.Events = new OAuthEvents() { OnRemoteFailure = HandleOnRemoteFailure }; }); } if (Convert.ToBoolean(Configuration["ExternalAuthProviders:Twitter:Enabled"] ?? "false")) { // You must first create an app with Twitter and add its key and Secret to your user-secrets. // https://apps.twitter.com/ // https://developer.twitter.com/en/docs/basics/authentication/api-reference/access_token authBuilder.AddTwitter(options => { options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme; options.ConsumerKey = Configuration["ExternalAuthProviders:Twitter:ConsumerKey"]; options.ConsumerSecret = Configuration["ExternalAuthProviders:Twitter:ConsumerSecret"]; // http://stackoverflow.com/questions/22627083/can-we-get-email-id-from-twitter-oauth-api/32852370#32852370 // http://stackoverflow.com/questions/36330675/get-users-email-from-twitter-api-for-external-login-authentication-asp-net-mvc?lq=1 options.RetrieveUserDetails = true; options.SaveTokens = true; options.ClaimActions.MapJsonKey("urn:twitter:profilepicture", "profile_image_url", ClaimTypes.Uri); options.Events = new TwitterEvents() { OnRemoteFailure = HandleOnRemoteFailure }; }); } //https://github.com/xamarin/Essentials/blob/master/Samples/Sample.Server.WebAuthenticator/Startup.cs if (Convert.ToBoolean(Configuration["ExternalAuthProviders:Apple:Enabled"] ?? "false")) { authBuilder.AddApple(options => { options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme; options.ClientId = Configuration["ExternalAuthProviders:Apple:ClientId"]; options.KeyId = Configuration["ExternalAuthProviders:Apple:KeyId"]; options.TeamId = Configuration["ExternalAuthProviders:Apple:TeamId"]; options.UsePrivateKey(keyId => _environment.ContentRootFileProvider.GetFileInfo($"AuthKey_{keyId}.p8")); options.SaveTokens = true; }); } // You must first create an app with Microsoft Account and add its ID and Secret to your user-secrets. // https://docs.microsoft.com/en-us/azure/active-directory/develop/quickstart-register-app if (Convert.ToBoolean(Configuration["ExternalAuthProviders:Microsoft:Enabled"] ?? "false")) { authBuilder.AddMicrosoftAccount(options => { options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme; options.ClientId = Configuration["ExternalAuthProviders:Microsoft:ClientId"]; options.ClientSecret = Configuration["ExternalAuthProviders:Microsoft:ClientSecret"]; options.SaveTokens = true; options.Scope.Add("offline_access"); options.Events = new OAuthEvents() { OnRemoteFailure = HandleOnRemoteFailure }; }); } #endregion #region Authorization //Add Policies / Claims / Authorization - https://identityserver4.readthedocs.io/en/latest/topics/add_apis.html#advanced services.AddAuthorization(options => { options.AddPolicy(Policies.IsAdmin, Policies.IsAdminPolicy()); options.AddPolicy(Policies.IsUser, Policies.IsUserPolicy()); options.AddPolicy(Policies.IsReadOnly, Policies.IsReadOnlyPolicy()); options.AddPolicy(Policies.IsMyDomain, Policies.IsMyDomainPolicy()); // valid only on serverside operations options.AddPolicy(Policies.TwoFactorEnabled, Policies.IsTwoFactorEnabledPolicy()); }); services.AddScoped <ApplicationPermissions>(); services.AddSingleton <IAuthorizationPolicyProvider, AuthorizationPolicyProvider>(); services.AddTransient <IAuthorizationHandler, DomainRequirementHandler>(); services.AddTransient <IAuthorizationHandler, PermissionRequirementHandler>(); #endregion services.Configure <IdentityOptions>(options => { // Password settings options.Password.RequireDigit = false; options.Password.RequiredLength = 6; options.Password.RequireNonAlphanumeric = false; options.Password.RequireUppercase = false; options.Password.RequireLowercase = false; //options.Password.RequiredUniqueChars = 6; // Lockout settings options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(30); options.Lockout.MaxFailedAccessAttempts = 10; options.Lockout.AllowedForNewUsers = true; // Require Confirmed Email User settings if (Convert.ToBoolean(Configuration[$"{projectName}:RequireConfirmedEmail"] ?? "false")) { options.User.RequireUniqueEmail = true; options.SignIn.RequireConfirmedEmail = true; } }); #region Cookies // cookie policy to deal with temporary browser incompatibilities services.AddSameSiteCookiePolicy(); //https://docs.microsoft.com/en-us/aspnet/core/security/gdpr services.Configure <CookiePolicyOptions>(options => { // This lambda determines whether user consent for non-essential // cookies is needed for a given request. options.CheckConsentNeeded = context => false; //consent not required // requires using Microsoft.AspNetCore.Http; //options.MinimumSameSitePolicy = SameSiteMode.None; }); //services.ConfigureExternalCookie(options => // { // macOS login fix //options.Cookie.SameSite = SameSiteMode.None; //}); services.ConfigureApplicationCookie(options => { options.Cookie.IsEssential = true; options.Cookie.HttpOnly = true; options.Cookie.SecurePolicy = CookieSecurePolicy.SameAsRequest; options.ExpireTimeSpan = TimeSpan.FromMinutes(60); options.LoginPath = Shared.Settings.LoginPath; //options.AccessDeniedPath = "/Identity/Account/AccessDenied"; // ReturnUrlParameter requires //using Microsoft.AspNetCore.Authentication.Cookies; options.ReturnUrlParameter = CookieAuthenticationDefaults.ReturnUrlParameter; options.SlidingExpiration = true; // Suppress redirect on API URLs in ASP.NET Core -> https://stackoverflow.com/a/56384729/54159 options.Events = new CookieAuthenticationEvents() { OnRedirectToAccessDenied = context => { if (context.Request.Path.StartsWithSegments("/api")) { context.Response.StatusCode = Status403Forbidden; } return(Task.CompletedTask); }, OnRedirectToLogin = context => { context.Response.StatusCode = Status401Unauthorized; return(Task.CompletedTask); } }; }); #endregion services.AddMvc().AddNewtonsoftJson(opt => { // Set Breeze defaults for entity serialization var ss = JsonSerializationFns.UpdateWithDefaults(opt.SerializerSettings); if (ss.ContractResolver is DefaultContractResolver resolver) { resolver.NamingStrategy = null; // remove json camelCasing; names are converted on the client. } if (_environment.IsDevelopment()) { ss.Formatting = Newtonsoft.Json.Formatting.Indented; // format JSON for debugging } }) // Add Breeze exception filter to send errors back to the client .AddMvcOptions(o => { o.Filters.Add(new GlobalExceptionFilter()); }); services.AddServerSideBlazor().AddCircuitOptions(o => { if (_environment.IsDevelopment()) { o.DetailedErrors = true; } }); services.AddSignalR(); if (_enableAPIDoc) { services.AddOpenApiDocument(document => { document.Title = "BlazorBoilerplate API"; document.Version = typeof(Startup).GetTypeInfo().Assembly.GetName().Version.ToString(); document.AddSecurity("bearer", Enumerable.Empty <string>(), new OpenApiSecurityScheme { Type = OpenApiSecuritySchemeType.OAuth2, Description = "Local Identity Server", OpenIdConnectUrl = $"{authAuthority}/.well-known/openid-configuration", //not working Flow = OpenApiOAuth2Flow.AccessCode, Flows = new OpenApiOAuthFlows() { AuthorizationCode = new OpenApiOAuthFlow() { Scopes = new Dictionary <string, string> { { LocalApi.ScopeName, IdentityServerConfig.LocalApiName } }, AuthorizationUrl = $"{authAuthority}/connect/authorize", TokenUrl = $"{authAuthority}/connect/token" }, } });; document.OperationProcessors.Add(new AspNetCoreOperationSecurityScopeProcessor("bearer")); // new OperationSecurityScopeProcessor("bearer")); }); } services.AddScoped <IUserSession, UserSession>(); services.AddSingleton <IHttpContextAccessor, HttpContextAccessor>(); services.Add(ServiceDescriptor.Scoped(typeof(ITenantSettings <>), typeof(TenantSettingsManager <>))); services.AddTransient <IAccountManager, AccountManager>(); services.AddTransient <IAdminManager, AdminManager>(); services.AddTransient <IEmailManager, EmailManager>(); services.AddTransient <IExternalAuthManager, ExternalAuthManager>(); services.AddTransient <IMessageManager, MessageManager>(); #region Automapper //Automapper to map DTO to Models https://www.c-sharpcorner.com/UploadFile/1492b1/crud-operations-using-automapper-in-mvc-application/ var automapperConfig = new MapperConfiguration(configuration => { configuration.AddProfile(new MappingProfile()); }); var autoMapper = automapperConfig.CreateMapper(); services.AddSingleton(autoMapper); #endregion /* ServerSideBlazor */ services.AddScoped <IAuthorizeApi, AuthorizeApi>(); services.AddScoped <AppState>(); // setup HttpClient for server side in a client side compatible fashion ( with auth cookie ) if (!services.Any(x => x.ServiceType == typeof(HttpClient))) { services.AddScoped(s => { // creating the URI helper needs to wait until the JS Runtime is initialized, so defer it. var navigationManager = s.GetRequiredService <NavigationManager>(); var httpContextAccessor = s.GetRequiredService <IHttpContextAccessor>(); var cookies = httpContextAccessor.HttpContext.Request.Cookies; var client = new HttpClient(new HttpClientHandler { UseCookies = false }); if (cookies.Any()) { var cks = new List <string>(); foreach (var cookie in cookies) { cks.Add($"{cookie.Key}={cookie.Value}"); } client.DefaultRequestHeaders.Add("Cookie", string.Join(';', cks)); } client.BaseAddress = new Uri(navigationManager.BaseUri); return(client); }); } services.AddScoped <IApiClient, ApiClient>(); // Authentication providers Log.Logger.Debug("Removing AuthenticationStateProvider..."); var serviceDescriptor = services.FirstOrDefault(descriptor => descriptor.ServiceType == typeof(AuthenticationStateProvider)); if (serviceDescriptor != null) { services.Remove(serviceDescriptor); } Log.Logger.Debug("Adding AuthenticationStateProvider..."); services.AddScoped <AuthenticationStateProvider, IdentityAuthenticationStateProvider>(); /**********************/ services.AddModules(); if (Log.Logger.IsEnabled(Serilog.Events.LogEventLevel.Debug)) { Log.Logger.Debug($"Total Services Registered: {services.Count}"); foreach (var service in services) { Log.Logger.Debug($"\n\tService: {service.ServiceType.FullName}\n\tLifetime: {service.Lifetime}\n\tInstance: {service.ImplementationType?.FullName}"); } } }
static void Main(string[] args) { X509Store store = new X509Store(StoreName.Root, StoreLocation.CurrentUser); store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly); X509Certificate2Collection collection = (X509Certificate2Collection)store.Certificates; X509Certificate2Collection fcollection = (X509Certificate2Collection)collection.Find(X509FindType.FindByTimeValid, DateTime.Now, false); foreach (var item in fcollection) { var x = item; Console.Write(x.Issuer); } X509Certificate2Collection scollection = X509Certificate2UI.SelectFromCollection(fcollection, "Test Certificate Select", "Select a certificate from the following list to get information on that certificate", X509SelectionFlag.MultiSelection); Console.WriteLine("Number of certificates: {0}{1}", scollection.Count, Environment.NewLine); //foreach (X509Certificate2 x509 in scollection) //{ // try // { // byte[] rawdata = x509.RawData; // //Console.WriteLine("Content Type: {0}{1}", X509Certificate2.GetCertContentType(rawdata), Environment.NewLine); // //Console.WriteLine("Friendly Name: {0}{1}", x509.FriendlyName, Environment.NewLine); // //Console.WriteLine("Certificate Verified?: {0}{1}", x509.Verify(), Environment.NewLine); // //Console.WriteLine("Simple Name: {0}{1}", x509.GetNameInfo(X509NameType.SimpleName, true), Environment.NewLine); // //Console.WriteLine("Signature Algorithm: {0}{1}", x509.SignatureAlgorithm.FriendlyName, Environment.NewLine); // //Console.WriteLine("Public Key: {0}{1}", x509.PublicKey.Key.ToXmlString(false), Environment.NewLine); // //Console.WriteLine("Certificate Archived?: {0}{1}", x509.Archived, Environment.NewLine); // //Console.WriteLine("Length of Raw Data: {0}{1}", x509.RawData.Length, Environment.NewLine); // Console.WriteLine("Vaidate: {0}{1}", x509.GetExpirationDateString(), Environment.NewLine); // Console.WriteLine("Effective: {0}{1}", x509.GetEffectiveDateString(), Environment.NewLine); // Console.WriteLine("IssuerName: {0}{1}", x509.IssuerName.ToString(), Environment.NewLine); // Console.WriteLine("IssuerName: {0}{1}", x509.GetEffectiveDateString(), Environment.NewLine); // X509Certificate2UI.DisplayCertificate(x509); // x509.Reset(); // } // catch (CryptographicException) // { // Console.WriteLine("Information could not be written out for this certificate."); // } //} //store.Close(); //Console.WriteLine("\r\nExists Certs Name and Location"); //Console.WriteLine("------ ----- -------------------------"); //foreach (StoreLocation storeLocation in (StoreLocation[]) // Enum.GetValues(typeof(StoreLocation))) //{ // foreach (StoreName storeName in (StoreName[]) // Enum.GetValues(typeof(StoreName))) // { // X509Store store = new X509Store(storeName, storeLocation); // try // { // store.Open(OpenFlags.OpenExistingOnly); // Console.WriteLine("Yes {0,4} {1}, {2}", // store.Certificates.Count, store.Name, store.Location); // } // catch (CryptographicException) // { // Console.WriteLine("No {0}, {1}", // store.Name, store.Location); // } // } // Console.WriteLine(); //} // The path to the certificate. string Certificate = "C:/Dev/Repos/Source/DotNetTestProjectRepo/CertManagment/shop.apak.se-all.pfx"; // Load the certificate into an X509Certificate object. X509Certificate cert = new X509Certificate(); cert.Import(Certificate); // Get the value. string resultsTrue = cert.ToString(true); // Display the value to the console. Console.WriteLine(resultsTrue); // Get the value. string resultsFalse = cert.ToString(false); // Display the value to the console. Console.WriteLine(resultsFalse); Console.ReadKey(); }
public static X509Certificate2 RetrieveCertificate(string subjectName) { X509Store store = null; X509Certificate2Collection certificates = null; X509Certificate2Collection certificates2 = null; try { store = new X509Store(StoreName.My, StoreLocation.LocalMachine); store.Open(OpenFlags.OpenExistingOnly); if (store.StoreHandle != IntPtr.Zero) { certificates2 = store.Certificates; certificates = certificates2.Find(X509FindType.FindBySubjectDistinguishedName, subjectName, true); if (certificates.Count == 0) { throw new ArgumentException("Certificate not found: " + subjectName, "subjectName"); } if (certificates.Count > 1) { throw new ArgumentException("More than one certificate found: " + subjectName, "subjectName"); } if (certificates.Count == 1) { if (certificates[0].HasPrivateKey) { try { var o = certificates[0].PrivateKey; return(new X509Certificate2(certificates[0])); } catch (Exception ex) { throw new ApplicationException("Can't read private key - ensure you have permissions", ex); } } else { throw new ApplicationException("No private key on selected certificate " + subjectName); } } } } finally { if (certificates != null) { for (int i = 0; i < certificates.Count; i++) { certificates[i].Reset(); } } if (certificates2 != null) { for (int j = 0; j < certificates2.Count; j++) { certificates2[j].Reset(); } } if (store != null) { store.Close(); } } return(null); }
/// <summary> /// The main entry point for the application. /// </summary> static int Main(string[] args) { System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; //Log File cleanup try { if (System.IO.File.Exists(Environment.ExpandEnvironmentVariables("%temp%\\devcdrcore.log"))) { var log = new System.IO.FileInfo(Environment.ExpandEnvironmentVariables("%temp%\\devcdrcore.log")); if (log.Length > 5242880) //File is more than 5MB { if (System.IO.File.Exists(Environment.ExpandEnvironmentVariables("%temp%\\devcdrcore_.log"))) { System.IO.File.Delete(Environment.ExpandEnvironmentVariables("%temp%\\devcdrcore_.log")); } System.IO.File.Move(Environment.ExpandEnvironmentVariables("%temp%\\devcdrcore.log"), Environment.ExpandEnvironmentVariables("%temp%\\devcdrcore_.log")); } } } catch { } Trace.Listeners.Add(new TextWriterTraceListener(Environment.ExpandEnvironmentVariables(Environment.ExpandEnvironmentVariables("%temp%\\devcdrcore.log")))); Trace.AutoFlush = true; //Add SigningCert to TrustedPublishers -> to allow PowerShell script signed by this certificate. try { X509Certificate executingCert = X509Certificate2.CreateFromSignedFile(Assembly.GetExecutingAssembly().Location); X509Store store = new X509Store(StoreName.TrustedPublisher, StoreLocation.LocalMachine); store.Open(OpenFlags.ReadWrite); store.Add(new X509Certificate2(executingCert)); } catch { } Trace.WriteLine("Starting DevCDRAgent... " + DateTime.Now.ToString()); Trace.Indent(); Trace.Flush(); if (System.Environment.UserInteractive) { string parameter = string.Concat(args); switch (parameter) { case "--install": ManagedInstallerClass.InstallHelper(new string[] { Assembly.GetExecutingAssembly().Location }); break; case "--uninstall": ManagedInstallerClass.InstallHelper(new string[] { "/u", Assembly.GetExecutingAssembly().Location }); break; default: if (args.ToList().Contains("--hidden")) { var handle = GetConsoleWindow(); // Hide ShowWindow(handle, 0); parameter = ""; } Console.WriteLine(string.Format("--- Zander Tools: DevCDR Service Version: {0} ---", Assembly.GetEntryAssembly().GetName().Version)); Console.WriteLine("Optional ServiceInstaller parameters: --install , --uninstall"); if (string.IsNullOrEmpty(parameter)) { parameter = Environment.MachineName.ToUpper() + ":" + Environment.UserName.ToUpper(); } Trace.WriteLine("Startup Parameter: " + parameter); Service1 ConsoleApp = new Service1(Environment.ExpandEnvironmentVariables(parameter)); ConsoleApp.Start(null); MinimizeFootprint(); Trace.WriteLine("Started... " + DateTime.Now.ToString()); Console.WriteLine("Press ENTER to terminate..."); Console.ReadLine(); ConsoleApp.Stop(); break; } return(0); } else { var sService = new Service1(Environment.MachineName); ServiceBase.Run(sService); return(sService.ExitCode); } }
/// <summary> /// Constructs scan job /// </summary> /// <param name="options">Scanner options</param> /// <param name="jobName">Name of the job</param> /// <param name="jobVersion">Version of the job</param> public ScanJob(Options options, string jobName, string jobVersion) : base(jobName, jobVersion) { // Basic scan job configuration this.UseThreading = true; this.MaximumThreads = options.Threads; this.TenantAdminSite = options.TenantAdminSite; this.OutputFolder = DateTime.Now.Ticks.ToString(); this.Separator = options.Separator; this.ExcludeOD4B = !options.IncludeOD4B; this.CsvFile = options.CsvFile; this.Tenant = options.Tenant; this.Urls = options.Urls; this.ClientTag = ConstructClientTag(jobName); // Authentication setup if (options.AuthenticationTypeProvided() == AuthenticationType.AppOnly) { this.UseAppOnlyAuthentication(options.ClientID, options.ClientSecret); } else if (options.AuthenticationTypeProvided() == AuthenticationType.AzureADAppOnly) { if (!string.IsNullOrEmpty(options.StoredCertificate)) { // Did we get a three part certificate path (= local stored cert) var certPath = options.StoredCertificate.Split(new string[] { "|" }, StringSplitOptions.RemoveEmptyEntries); if (certPath.Length == 3 && (certPath[1].Equals("CurrentUser", StringComparison.InvariantCultureIgnoreCase) || certPath[1].Equals("LocalMachine", StringComparison.InvariantCultureIgnoreCase))) { // Load the Azure cert based upon this string certThumbPrint = certPath[2].ToUpper(); Enum.TryParse(certPath[0], out StoreName storeName); Enum.TryParse(certPath[1], out StoreLocation storeLocation); var store = new X509Store(storeName, storeLocation); store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly); var certificateCollection = store.Certificates.Find(X509FindType.FindByThumbprint, certThumbPrint, false); store.Close(); foreach (var certificate in certificateCollection) { if (certificate.Thumbprint == certThumbPrint) { options.AzureCert = certificate; break; } } } if (options.AzureCert == null) { throw new Exception($"No valid certificate found for provided path {options.StoredCertificate}"); } } else { var certificatePassword = EncryptionUtility.ToSecureString(options.CertificatePfxPassword); using (var certfile = System.IO.File.OpenRead(options.CertificatePfx)) { var certificateBytes = new byte[certfile.Length]; certfile.Read(certificateBytes, 0, (int)certfile.Length); var cert = new X509Certificate2( certificateBytes, certificatePassword, X509KeyStorageFlags.Exportable | X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet); options.AzureCert = cert; } } this.UseAzureADAppOnlyAuthentication(options.ClientID, options.AzureTenant, options.AzureCert); } else if (options.AuthenticationTypeProvided() == AuthenticationType.Office365) { this.UseOffice365Authentication(options.User, options.Password); } // Configure sites to scan if (!String.IsNullOrEmpty(this.Tenant)) { this.AddSite(string.Format("https://{0}.sharepoint.com*", this.Tenant)); this.AddSite(string.Format("https://{0}-my.sharepoint.com*", this.Tenant)); } else if (this.Urls != null && this.Urls.Count > 0) { foreach (var url in this.Urls) { this.AddSite(url.Trim()); } } else if (!String.IsNullOrEmpty(this.CsvFile)) { foreach (var row in LoadSitesFromCsv(this.CsvFile, this.Separator.ToCharArray().First())) { this.AddSite(row[0].Trim()); //first column in the row contains url } } else { Console.WriteLine("No site selection specified, assume the job will use search to retrieve a list of sites"); } this.StartTime = DateTime.Now; }
/// <summary> /// Creates a cert with the connectionstring (token) and stores it in the given cert store. /// </summary> public async static Task WriteAsync(string name, string connectionString, string storeType, string storePath) { if (string.IsNullOrEmpty(connectionString)) { throw new ArgumentException("Token not found in X509Store and no new token provided!"); } SecureRandom random = new SecureRandom(); KeyGenerationParameters keyGenerationParameters = new KeyGenerationParameters(random, 2048); RsaKeyPairGenerator keyPairGenerator = new RsaKeyPairGenerator(); keyPairGenerator.Init(keyGenerationParameters); AsymmetricCipherKeyPair keys = keyPairGenerator.GenerateKeyPair(); ArrayList nameOids = new ArrayList(); nameOids.Add(X509Name.CN); ArrayList nameValues = new ArrayList(); nameValues.Add(name); X509Name subjectDN = new X509Name(nameOids, nameValues); X509Name issuerDN = subjectDN; X509V3CertificateGenerator cg = new X509V3CertificateGenerator(); cg.SetSerialNumber(BigIntegers.CreateRandomInRange(BigInteger.One, BigInteger.ValueOf(Int64.MaxValue), random)); cg.SetIssuerDN(issuerDN); cg.SetSubjectDN(subjectDN); cg.SetNotBefore(DateTime.Now); cg.SetNotAfter(DateTime.Now.AddMonths(12)); cg.SetPublicKey(keys.Public); cg.AddExtension(X509Extensions.KeyUsage, true, new KeyUsage(KeyUsage.DataEncipherment)); // encrypt the token with the public key so only the owner of the assoc. private key can decrypt it and // "hide" it in the instruction code cert extension RSA rsa = RSA.Create(); RSAParameters rsaParams = new RSAParameters(); RsaKeyParameters keyParams = (RsaKeyParameters)keys.Public; rsaParams.Modulus = new byte[keyParams.Modulus.ToByteArrayUnsigned().Length]; keyParams.Modulus.ToByteArrayUnsigned().CopyTo(rsaParams.Modulus, 0); rsaParams.Exponent = new byte[keyParams.Exponent.ToByteArrayUnsigned().Length]; keyParams.Exponent.ToByteArrayUnsigned().CopyTo(rsaParams.Exponent, 0); rsa.ImportParameters(rsaParams); if (rsa != null) { byte[] bytes = rsa.Encrypt(Encoding.ASCII.GetBytes(connectionString), RSAEncryptionPadding.OaepSHA1); if (bytes != null) { cg.AddExtension(X509Extensions.InstructionCode, false, bytes); } else { throw new CryptographicException("Can not encrypt IoTHub security token using generated public key!"); } } // sign the cert with the private key ISignatureFactory signatureFactory = new Asn1SignatureFactory("SHA256WITHRSA", keys.Private, random); Org.BouncyCastle.X509.X509Certificate x509 = cg.Generate(signatureFactory); // create a PKCS12 store for the cert and its private key X509Certificate2 certificate = null; using (MemoryStream pfxData = new MemoryStream()) { Pkcs12StoreBuilder builder = new Pkcs12StoreBuilder(); builder.SetUseDerEncoding(true); Pkcs12Store pkcsStore = builder.Build(); X509CertificateEntry[] chain = new X509CertificateEntry[1]; string passcode = Guid.NewGuid().ToString(); chain[0] = new X509CertificateEntry(x509); pkcsStore.SetKeyEntry(name, new AsymmetricKeyEntry(keys.Private), chain); pkcsStore.Save(pfxData, passcode.ToCharArray(), random); // create X509Certificate2 object from PKCS12 file certificate = CertificateFactory.CreateCertificateFromPKCS12(pfxData.ToArray(), passcode); // handle each store type differently switch (storeType) { case CertificateStoreType.Directory: { // Add to DirectoryStore using (DirectoryCertificateStore store = new DirectoryCertificateStore()) { store.Open(storePath); X509CertificateCollection certificates = await store.Enumerate().ConfigureAwait(false); // remove any existing cert with our name from the store foreach (X509Certificate2 cert in certificates) { if (cert.SubjectName.Decode(X500DistinguishedNameFlags.None | X500DistinguishedNameFlags.DoNotUseQuotes).Equals("CN=" + name, StringComparison.OrdinalIgnoreCase)) { await store.Delete(cert.Thumbprint).ConfigureAwait(false); } } // add new one await store.Add(certificate).ConfigureAwait(false); } break; } case CertificateStoreType.X509Store: { // Add to X509Store using (X509Store store = new X509Store(storePath, StoreLocation.CurrentUser)) { store.Open(OpenFlags.ReadWrite); // remove any existing cert with our name from the store foreach (X509Certificate2 cert in store.Certificates) { if (cert.SubjectName.Decode(X500DistinguishedNameFlags.None | X500DistinguishedNameFlags.DoNotUseQuotes).Equals("CN=" + name, StringComparison.OrdinalIgnoreCase)) { store.Remove(cert); } } // add new cert to store try { store.Add(certificate); } catch (Exception e) { throw new Exception($"Not able to add cert to the requested store type '{storeType}' (exception message: '{e.Message}'."); } } break; } default: { throw new Exception($"The requested store type '{storeType}' is not supported. Please change."); } } return; } }
private void SetRequestHandleClientCertificateOptions(SafeWinHttpHandle requestHandle, Uri requestUri) { // Must be HTTPS scheme to use client certificates. if (requestUri.Scheme != UriSchemeHttps) { return; } // Get candidate list for client certificates. X509Certificate2Collection certs; if (_clientCertificateOption == ClientCertificateOption.Manual) { certs = ClientCertificates; } else { using (var myStore = new X509Store()) { myStore.Open(OpenFlags.OpenExistingOnly | OpenFlags.ReadOnly); certs = myStore.Certificates; } } // Check for no certs now as a performance optimization. if (certs.Count == 0) { SetNoClientCertificate(requestHandle); return; } // Reduce the set of certificates to match the proper 'Client Authentication' criteria. certs = certs.Find(X509FindType.FindByKeyUsage, X509KeyUsageFlags.DigitalSignature, true); certs = certs.Find(X509FindType.FindByApplicationPolicy, ClientAuthenticationOID, true); // Build a new collection with certs that have a private key. Need to do this // manually because there is no X509FindType to match this criteria. var clientCerts = new X509Certificate2Collection(); foreach (var cert in certs) { if (cert.HasPrivateKey) { clientCerts.Add(cert); } } // TOOD: Filter the list based on TrustedIssuerList info from WINHTTP. // Set the client certificate. if (certs.Count == 0) { SetNoClientCertificate(requestHandle); } else { SetWinHttpOption( requestHandle, Interop.WinHttp.WINHTTP_OPTION_CLIENT_CERT_CONTEXT, clientCerts[0].Handle, (uint)Marshal.SizeOf<Interop.Crypt32.CERT_CONTEXT>()); } }
private static X509Certificate2 FindX509Certificate(string thumbprint) { X509Store certificateStore = null; X509Certificate2 certificate = null; try { certificateStore = new X509Store(StoreName.My, StoreLocation.CurrentUser); certificateStore.Open(OpenFlags.ReadOnly); var certificates = certificateStore.Certificates.Find(X509FindType.FindByThumbprint, thumbprint, false); if (certificates.Count > 0) { certificate = certificates[0]; } } finally { if (certificateStore != null) certificateStore.Close(); } return certificate; }
public async Task SslStream_ClientCertificate_SendsChain() { List <SslStream> streams = new List <SslStream>(); TestHelper.CleanupCertificates(); (X509Certificate2 clientCertificate, X509Certificate2Collection clientChain) = TestHelper.GenerateCertificates("SslStream_ClinetCertificate_SendsChain", serverCertificate: false); using (X509Store store = new X509Store(StoreName.CertificateAuthority, StoreLocation.CurrentUser)) { // add chain certificate so we can construct chain since there is no way how to pass intermediates directly. store.Open(OpenFlags.ReadWrite); store.AddRange(clientChain); store.Close(); } using (var chain = new X509Chain()) { chain.ChainPolicy.VerificationFlags = X509VerificationFlags.AllFlags; chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck; chain.ChainPolicy.DisableCertificateDownloads = false; bool chainStatus = chain.Build(clientCertificate); // Verify we can construct full chain if (chain.ChainElements.Count < clientChain.Count) { throw new SkipTestException($"chain cannot be built {chain.ChainElements.Count}"); } } var clientOptions = new SslClientAuthenticationOptions() { TargetHost = "localhost", }; clientOptions.RemoteCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true; clientOptions.LocalCertificateSelectionCallback = (sender, target, certificates, remoteCertificate, issuers) => clientCertificate; var serverOptions = new SslServerAuthenticationOptions() { ClientCertificateRequired = true }; serverOptions.ServerCertificateContext = SslStreamCertificateContext.Create(Configuration.Certificates.GetServerCertificate(), null); serverOptions.RemoteCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => { // Client should send chain without root CA. There is no good way how to know if the chain was built from certificates // from wire or from system store. However, SslStream adds certificates from wire to ExtraStore in RemoteCertificateValidationCallback. // So we verify the operation by checking the ExtraStore. On Windows, that includes leaf itself. _output.WriteLine("RemoteCertificateValidationCallback called with {0} and {1} extra certificates", sslPolicyErrors, chain.ChainPolicy.ExtraStore.Count); foreach (X509Certificate c in chain.ChainPolicy.ExtraStore) { _output.WriteLine("received {0}", c.Subject); } Assert.True(chain.ChainPolicy.ExtraStore.Count >= clientChain.Count - 1, "client did not sent expected chain"); return(true); }; // run the test multiple times while holding established SSL so we could hit credential cache. for (int i = 0; i < 3; i++) { (Stream clientStream, Stream serverStream) = TestHelper.GetConnectedStreams(); SslStream client = new SslStream(clientStream); SslStream server = new SslStream(serverStream); Task t1 = client.AuthenticateAsClientAsync(clientOptions, CancellationToken.None); Task t2 = server.AuthenticateAsServerAsync(serverOptions, CancellationToken.None); await Task.WhenAll(t1, t2).WaitAsync(TestConfiguration.PassingTestTimeout); // hold to the streams so they stay in credential cache streams.Add(client); streams.Add(server); } TestHelper.CleanupCertificates(); clientCertificate.Dispose(); foreach (X509Certificate c in clientChain) { c.Dispose(); } foreach (SslStream s in streams) { s.Dispose(); } }
protected override void ProcessRecord() { var record = new PSObject(); var token = AzureAuthHelper.AuthenticateAsync(Tenant).GetAwaiter().GetResult(); var cert = new X509Certificate2(); if (ParameterSetName == ParameterSet_EXISTINGCERT) { if (ParameterSpecified(nameof(CertificatePassword))) { cert.Import(CertificatePath, CertificatePassword, X509KeyStorageFlags.Exportable); } else { cert.Import(CertificatePath); } } else { // Generate a certificate var x500Values = new List <string>(); if (!MyInvocation.BoundParameters.ContainsKey("CommonName")) { CommonName = ApplicationName; } if (!string.IsNullOrWhiteSpace(CommonName)) { x500Values.Add($"CN={CommonName}"); } if (!string.IsNullOrWhiteSpace(Country)) { x500Values.Add($"C={Country}"); } if (!string.IsNullOrWhiteSpace(State)) { x500Values.Add($"S={State}"); } if (!string.IsNullOrWhiteSpace(Locality)) { x500Values.Add($"L={Locality}"); } if (!string.IsNullOrWhiteSpace(Organization)) { x500Values.Add($"O={Organization}"); } if (!string.IsNullOrWhiteSpace(OrganizationUnit)) { x500Values.Add($"OU={OrganizationUnit}"); } string x500 = string.Join("; ", x500Values); if (ValidYears < 1 || ValidYears > 30) { ValidYears = 10; } DateTime validFrom = DateTime.Today; DateTime validTo = validFrom.AddYears(ValidYears); byte[] certificateBytes = CertificateHelper.CreateSelfSignCertificatePfx(x500, validFrom, validTo, CertificatePassword); cert = new X509Certificate2(certificateBytes, CertificatePassword, X509KeyStorageFlags.Exportable | X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet); if (!string.IsNullOrWhiteSpace(OutPath)) { if (!Path.IsPathRooted(OutPath)) { OutPath = Path.Combine(SessionState.Path.CurrentFileSystemLocation.Path, OutPath); } if (System.IO.Directory.Exists(OutPath)) { var pfxPath = Path.Combine(OutPath, $"{ApplicationName}.pfx"); byte[] certPfxData = cert.Export(X509ContentType.Pfx, CertificatePassword); File.WriteAllBytes(pfxPath, certPfxData); record.Properties.Add(new PSVariableProperty(new PSVariable("Pfx file", pfxPath))); var cerPath = Path.Combine(OutPath, $"{ApplicationName}.cer"); byte[] certCerData = cert.Export(X509ContentType.Cert); File.WriteAllBytes(cerPath, certCerData); record.Properties.Add(new PSVariableProperty(new PSVariable("Cer file", cerPath))); } } if (ParameterSpecified(nameof(Store))) { using (var store = new X509Store("My", Store)) { store.Open(OpenFlags.ReadWrite); store.Add(cert); store.Close(); } Host.UI.WriteLine(ConsoleColor.Yellow, Host.UI.RawUI.BackgroundColor, "Certificate added to store"); } } var expirationDate = DateTime.Parse(cert.GetExpirationDateString()).ToUniversalTime(); var startDate = DateTime.Parse(cert.GetEffectiveDateString()).ToUniversalTime(); if (token != null) { var permissionScopes = new PermissionScopes(); var scopes = new List <PermissionScope>(); if (this.Scopes != null) { foreach (var scopeIdentifier in this.Scopes) { scopes.Add(permissionScopes.GetScope(scopeIdentifier)); } } else { scopes.Add(permissionScopes.GetScope("SPO.Sites.FullControl.All")); scopes.Add(permissionScopes.GetScope("MSGraph.Group.ReadWrite.All")); scopes.Add(permissionScopes.GetScope("SPO.User.Read.All")); scopes.Add(permissionScopes.GetScope("MSGraph.User.Read.All")); } var scopesPayload = GetScopesPayload(scopes); var payload = new { displayName = ApplicationName, signInAudience = "AzureADMyOrg", keyCredentials = new[] { new { customKeyIdentifier = cert.GetCertHashString(), endDateTime = expirationDate, keyId = Guid.NewGuid().ToString(), startDateTime = startDate, type = "AsymmetricX509Cert", usage = "Verify", key = Convert.ToBase64String(cert.GetRawCertData()) } }, publicClient = new { redirectUris = new[] { "https://login.microsoftonline.com/common/oauth2/nativeclient", } }, requiredResourceAccess = scopesPayload }; var postResult = HttpHelper.MakePostRequestForString("https://graph.microsoft.com/beta/applications", payload, "application/json", token); var azureApp = JsonConvert.DeserializeObject <AzureApp>(postResult); record.Properties.Add(new PSVariableProperty(new PSVariable("AzureAppId", azureApp.AppId))); var waitTime = 60; this.Host.UI.Write(ConsoleColor.Yellow, this.Host.UI.RawUI.BackgroundColor, $"Waiting {waitTime} seconds to launch consent flow in a browser window. This wait is required to make sure that Azure AD is able to initialize all required artifacts."); for (var i = 0; i < waitTime; i++) { this.Host.UI.Write(ConsoleColor.Yellow, this.Host.UI.RawUI.BackgroundColor, "."); System.Threading.Thread.Sleep(1000); } this.Host.UI.WriteLine(); var consentUrl = $"https://login.microsoftonline.com/{Tenant}/v2.0/adminconsent?client_id={azureApp.AppId}&scope=https://microsoft.sharepoint-df.com/.default"; record.Properties.Add(new PSVariableProperty(new PSVariable("Certificate Thumbprint", cert.GetCertHashString()))); AzureAuthHelper.OpenConsentFlow(consentUrl, (message) => { this.Host.UI.WriteLine(ConsoleColor.Red, this.Host.UI.RawUI.BackgroundColor, message); }); WriteObject(record); } }
private SslStreamCertificateContext(X509Certificate2 target, X509Certificate2[] intermediates) { if (intermediates.Length > 0) { using (X509Chain chain = new X509Chain()) { chain.ChainPolicy.VerificationFlags = X509VerificationFlags.AllFlags; chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck; chain.ChainPolicy.DisableCertificateDownloads = true; bool osCanBuildChain = chain.Build(target); int count = 0; foreach (X509ChainStatus status in chain.ChainStatus) { if (status.Status.HasFlag(X509ChainStatusFlags.PartialChain) || status.Status.HasFlag(X509ChainStatusFlags.NotSignatureValid)) { osCanBuildChain = false; break; } count++; } // OS failed to build the chain but we have at least some intermediates. // We will try to add them to "Intermediate Certification Authorities" store. if (!osCanBuildChain) { X509Store?store = new X509Store(StoreName.CertificateAuthority, StoreLocation.LocalMachine); try { store.Open(OpenFlags.ReadWrite); } catch { // If using system store fails, try to fall-back to user store. store.Dispose(); store = new X509Store(StoreName.CertificateAuthority, StoreLocation.CurrentUser); try { store.Open(OpenFlags.ReadWrite); } catch { store.Dispose(); store = null; if (NetEventSource.IsEnabled) { NetEventSource.Error(this, $"Failed to open certificate store for intermediates."); } } } if (store != null) { using (store) { // Add everything except the root for (int index = count; index < intermediates.Length - 1; index++) { store.Add(intermediates[index]); } osCanBuildChain = chain.Build(target); foreach (X509ChainStatus status in chain.ChainStatus) { if (status.Status.HasFlag(X509ChainStatusFlags.PartialChain) || status.Status.HasFlag(X509ChainStatusFlags.NotSignatureValid)) { osCanBuildChain = false; break; } } if (!osCanBuildChain) { // Add also root to Intermediate CA store so OS can complete building chain. // (This does not make it trusted. store.Add(intermediates[intermediates.Length - 1]); } } } } } } Certificate = target; IntermediateCertificates = intermediates; }
static async Task Connect(bool useTls, bool addCaCertToStore, bool useServerCertificateValidationCallback) { await Console.Out.WriteLineAsync("Press Enter to connect to Websocket server.").ConfigureAwait(false); Console.ReadLine(); try { var caCert = new X509Certificate2("sample_ca.cer"); X509Store store = new X509Store(StoreName.Root, StoreLocation.CurrentUser); store.Open(OpenFlags.ReadWrite); var certs = store.Certificates.Find(X509FindType.FindByThumbprint, caCert.Thumbprint, false); if (certs.Count == 0 && addCaCertToStore) { store.Add(caCert); } else if (certs.Count > 0 && !addCaCertToStore) { store.Remove(caCert); } store.Close(); var webSocket = new ClientWebSocket(); //NOTE: It would not be expected for this to work, but I may as well show it // as to avoid getting comments like 'did you try...' This approach should // work for a self-signed certificate, however. //webSocket.Options.ClientCertificates.Add(caCert); //add the CA cert. // For giggles, add the cert issued by caCert. Again, this should not work as it is issued // by an untrusted CA. //webSocket.Options.ClientCertificates.Add(new X509Certificate2(@"..\..\..\FleckServer\bin\debug\sample_cert.cer")); var uriPrefix = "ws:"; if (useTls) { uriPrefix = "wss:"; ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; } if (useServerCertificateValidationCallback) { ServicePointManager.ServerCertificateValidationCallback += (sender, certificate, chain, errors) => { if (errors == SslPolicyErrors.None) { return(true); } //BUGBUG: Obviously there should be a much more extensive check here. if (certificate.Issuer == caCert.Issuer) { return(true); } return(false); }; } await webSocket.ConnectAsync(new Uri($"{uriPrefix}//localhost:8181"), CancellationToken.None).ConfigureAwait(false); Task.Run(() => Receive(webSocket)); await Console.Out.WriteLineAsync("Type line to send to websocket, Enter key sends it. 'exit' to exit.").ConfigureAwait(false); string input = Console.ReadLine(); while (input != "exit") { var bytes = new ArraySegment <byte>(Encoding.UTF8.GetBytes(input)); await webSocket.SendAsync(bytes, WebSocketMessageType.Text, true, CancellationToken.None).ConfigureAwait(false); input = Console.ReadLine(); } await Console.Out.WriteLineAsync("Goodbye.").ConfigureAwait(false); } catch (Exception e) { await Console.Out.WriteLineAsync(e.ToString()).ConfigureAwait(false); } }
// // Security: We temporarily reset thread token to open the cert store under process account. // internal static X509Store EnsureStoreOpened(bool isMachineStore) { X509Store store = isMachineStore ? s_myMachineCertStoreEx : s_myCertStoreEx; // TODO #3862 Investigate if this can be switched to either the static or Lazy<T> patterns. if (Volatile.Read(ref store) == null) { lock (s_syncObject) { store = isMachineStore ? s_myMachineCertStoreEx : s_myCertStoreEx; if (Volatile.Read(ref store) == null) { // NOTE: that if this call fails we won't keep track and the next time we enter we will try to open the store again. StoreLocation storeLocation = isMachineStore ? StoreLocation.LocalMachine : StoreLocation.CurrentUser; store = new X509Store(StoreName.My, storeLocation); try { // For app-compat We want to ensure the store is opened under the **process** account. try { WindowsIdentity.RunImpersonated(SafeAccessTokenHandle.InvalidHandle, () => { store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly); GlobalLog.Print("SecureChannel::EnsureStoreOpened() storeLocation:" + storeLocation + " returned store:" + store.GetHashCode().ToString("x")); }); } catch { throw; } if (isMachineStore) { s_myMachineCertStoreEx = store; } else { s_myCertStoreEx = store; } return(store); } catch (Exception exception) { if (exception is CryptographicException || exception is SecurityException) { GlobalLog.Assert("SecureChannel::EnsureStoreOpened()", "Failed to open cert store, location:" + storeLocation + " exception:" + exception); return(null); } if (NetEventSource.Log.IsEnabled()) { NetEventSource.PrintError(NetEventSource.ComponentType.Security, SR.Format(SR.net_log_open_store_failed, storeLocation, exception)); } throw; } } } } return(store); }
/// <summary> /// Finds all valid installed certificates /// </summary> public static void FindCertificates() { string[] ValidCertificatePrefixes = { "iPhone Developer", "iPhone Distribution", "Apple Development", "Apple Distribution" }; X509Certificate2Collection FoundCerts = new X509Certificate2Collection(); if (Environment.OSVersion.Platform == PlatformID.Unix || Environment.OSVersion.Platform == PlatformID.MacOSX) { foreach (string SearchPrefix in ValidCertificatePrefixes) { // run certtool y to get the currently installed certificates CertToolData = ""; Process CertTool = new Process(); CertTool.StartInfo.FileName = "/usr/bin/security"; CertTool.StartInfo.UseShellExecute = false; CertTool.StartInfo.Arguments = string.Format("find-certificate -a -c \"{0}\" -p", SearchPrefix); CertTool.StartInfo.RedirectStandardOutput = true; CertTool.OutputDataReceived += new DataReceivedEventHandler(OutputReceivedCertToolProcessCall); CertTool.Start(); CertTool.BeginOutputReadLine(); CertTool.WaitForExit(); if (CertTool.ExitCode == 0) { string header = "-----BEGIN CERTIFICATE-----\n"; string footer = "-----END CERTIFICATE-----"; int start = CertToolData.IndexOf(header); while (start != -1) { start += header.Length; int end = CertToolData.IndexOf(footer, start); string base64 = CertToolData.Substring(start, (end - start)); byte[] certData = Convert.FromBase64String(base64); X509Certificate2 cert = new X509Certificate2(certData); FoundCerts.Add(cert); start = CertToolData.IndexOf(header, start); } } } } else { // Open the personal certificate store on this machine X509Store Store = new X509Store(); Store.Open(OpenFlags.ReadOnly); foreach (string SearchPrefix in ValidCertificatePrefixes) { FoundCerts.AddRange(Store.Certificates.Find(X509FindType.FindBySubjectName, SearchPrefix, false)); } Store.Close(); } foreach (X509Certificate2 TestCert in FoundCerts) { DateTime EffectiveDate = TestCert.NotBefore.ToUniversalTime(); DateTime ExpirationDate = TestCert.NotAfter.ToUniversalTime(); DateTime Now = DateTime.UtcNow; bool bCertTimeIsValid = (EffectiveDate < Now) && (ExpirationDate > Now); Program.LogVerbose("CERTIFICATE-Name:{0},Validity:{1},StartDate:{2},EndDate:{3}", CryptoAdapter.GetFriendlyNameFromCert(TestCert), bCertTimeIsValid ? "VALID" : "EXPIRED", EffectiveDate.ToString("o"), ExpirationDate.ToString("o")); } }
private static void RemoveCertificatesFromStore(StoreName storeName, StoreLocation storeLocation, CommandLineArgs commandLineArgs) { Console.WriteLine(" Checking StoreName '{0}', StoreLocation '{1}'", storeName, storeLocation); using (X509Store store = new X509Store(storeName, storeLocation)) { try { store.Open(OpenFlags.ReadWrite | OpenFlags.IncludeArchived); } catch (CryptographicException cEx) { StringBuilder exceptionString = new StringBuilder(); exceptionString.AppendFormat(" Error opening StoreName: '{0}' certificate store from StoreLocation '{1}' in ReadWrite mode ", storeName, storeLocation); if (storeLocation == StoreLocation.LocalMachine) { exceptionString.AppendFormat("{0} In Windows, This is usually due to permissions issues if writing to the LocalMachine location", Environment.NewLine); } exceptionString.AppendFormat("{0} Try running the tool with elevated or superuser permissions.", Environment.NewLine); exceptionString.Append(GetExceptionString(commandLineArgs, cEx)); Console.WriteLine(exceptionString.ToString()); } catch (PlatformNotSupportedException pnse) { StringBuilder exceptionString = new StringBuilder(); exceptionString.AppendFormat(" Error opening StoreName: '{0}' certificate store from StoreLocation '{1}' in ReadWrite mode ", storeName, storeLocation); if (storeLocation == StoreLocation.LocalMachine) { exceptionString.AppendFormat("{0} In Linux, this is an expected exception as opening a certificate store ReadWrite to LocalMachine isn't yet supported", Environment.NewLine); } exceptionString.Append(GetExceptionString(commandLineArgs, pnse)); Console.WriteLine(exceptionString.ToString()); } catch (Exception ex) { StringBuilder exceptionString = new StringBuilder(); exceptionString.AppendFormat(" Error opening StoreName: '{0}' certificate store from StoreLocation '{1}' in ReadWrite mode ", storeName, storeLocation); exceptionString.Append(GetExceptionString(commandLineArgs, ex)); Console.WriteLine(exceptionString.ToString()); } int removedCerts = 0; foreach (var cert in store.Certificates.Find(X509FindType.FindByIssuerName, CertificateIssuer, false)) { Console.Write(" {0}. Subject: '{1}'", cert.Thumbprint, cert.SubjectName.Name); if (!commandLineArgs.Preview) { try { store.Remove(cert); Console.Write(" ... removed"); removedCerts++; } catch (Exception ex) { Console.Write(" ... cert removal failed"); Console.WriteLine(GetExceptionString(commandLineArgs, ex)); } } Console.WriteLine(); } if (!commandLineArgs.Preview) { Console.WriteLine(" {0} certificates removed", removedCerts); } } Console.WriteLine(); }
/// <summary> /// Tries to find a matching certificate on this machine from the the serial number of one of the /// certificates in the mobile provision (the one in the mobileprovision is missing the public/private key pair) /// </summary> public static X509Certificate2 FindCertificate(MobileProvision ProvisionToWorkFrom) { Program.LogVerbose(" Looking for a certificate that matches the application identifier '{0}'", ProvisionToWorkFrom.ApplicationIdentifier); X509Certificate2 Result = null; if (Environment.OSVersion.Platform == PlatformID.Unix || Environment.OSVersion.Platform == PlatformID.MacOSX) { // run certtool y to get the currently installed certificates CertToolData = ""; Process CertTool = new Process(); CertTool.StartInfo.FileName = "/usr/bin/security"; CertTool.StartInfo.UseShellExecute = false; CertTool.StartInfo.Arguments = "find-identity -p codesigning -v"; CertTool.StartInfo.RedirectStandardOutput = true; CertTool.OutputDataReceived += new DataReceivedEventHandler(OutputReceivedCertToolProcessCall); CertTool.Start(); CertTool.BeginOutputReadLine(); CertTool.WaitForExit(); if (CertTool.ExitCode == 0) { foreach (X509Certificate2 SourceCert in ProvisionToWorkFrom.DeveloperCertificates) { X509Certificate2 ValidInTimeCert = null; // see if certificate can be found by serial number string CertHash = SourceCert.GetCertHashString(); if (CertToolData.Contains(CertHash)) { ValidInTimeCert = SourceCert; } if (ValidInTimeCert != null) { // Found a cert in the valid time range, quit now! Result = ValidInTimeCert; break; } } } } else { // Open the personal certificate store on this machine X509Store Store = new X509Store(); Store.Open(OpenFlags.ReadOnly); // Try finding a matching certificate from the serial number (the one in the mobileprovision is missing the public/private key pair) foreach (X509Certificate2 SourceCert in ProvisionToWorkFrom.DeveloperCertificates) { X509Certificate2Collection FoundCerts = Store.Certificates.Find(X509FindType.FindBySerialNumber, SourceCert.SerialNumber, false); Program.LogVerbose(" .. Provision entry SN '{0}' matched {1} installed certificate(s)", SourceCert.SerialNumber, FoundCerts.Count); X509Certificate2 ValidInTimeCert = null; foreach (X509Certificate2 TestCert in FoundCerts) { DateTime EffectiveDate = TestCert.NotBefore.ToUniversalTime(); DateTime ExpirationDate = TestCert.NotAfter.ToUniversalTime(); DateTime Now = DateTime.UtcNow; bool bCertTimeIsValid = (EffectiveDate < Now) && (ExpirationDate > Now); Program.LogVerbose(" .. .. Installed certificate '{0}' is {1} (range '{2}' to '{3}')", CryptoAdapter.GetFriendlyNameFromCert(TestCert), bCertTimeIsValid ? "valid (choosing it)" : "EXPIRED", TestCert.GetEffectiveDateString(), TestCert.GetExpirationDateString()); if (bCertTimeIsValid) { ValidInTimeCert = TestCert; break; } } if (ValidInTimeCert != null) { // Found a cert in the valid time range, quit now! Result = ValidInTimeCert; break; } } Store.Close(); } if (Result == null) { Program.LogVerbose(" .. Failed to find a valid certificate that was in date"); } return(Result); }
/// <summary> /// Verify, that certificate was installed and HttpListener was configured correct /// </summary> private void VerifyCertificateAndConfigurationOfHttpListener() { if (radioButtonUseSSLAccelerator.Checked) { return; } string thumbprint = ""; if (radioButtonUseTestCertificate.Checked) { const string testRootCertName = "Confirmit CATI Root Test Certificate"; var storeMy = (StoreName)Enum.Parse(typeof(StoreName), "My", true); var storeRoot = (StoreName)Enum.Parse(typeof(StoreName), "Root", true); var storeLocation = (StoreLocation)Enum.Parse(typeof(StoreLocation), "LocalMachine", true); var store = new X509Store(storeMy, storeLocation); store.Open(OpenFlags.ReadOnly); X509Certificate2Collection cers = store.Certificates; cers = cers.Find(X509FindType.FindByIssuerName, testRootCertName, false); if (cers.Count == 0) { AddResultValue("Test certificate doesn't find in My/LocalMachine store"); } else { thumbprint = cers[0].Thumbprint; } store.Close(); store = new X509Store(storeRoot, storeLocation); store.Open(OpenFlags.ReadOnly); cers = store.Certificates; cers = cers.Find(X509FindType.FindByIssuerName, testRootCertName, false); cers = cers.Find(X509FindType.FindBySubjectDistinguishedName, "CN=" + testRootCertName, false); if (cers.Count == 0) { AddResultValue("Test certificate doesn't find in Root/LocalMachine store"); } store.Close(); string certPath = Path.Combine(textBoxCatiLocation.Text, @"TestCertificates\" + textBoxTestCertificateName.Text + ".cer"); if (!File.Exists(certPath)) { AddResultValue("Test certificate file \"" + certPath + "\" doesn't find"); } } else { thumbprint = textBoxRealCertificateThumbprint.Text; } string sslCertsStr = InvokeExternalScript("netsh.exe", "http show sslcert", 3000); if (!sslCertsStr.Contains("0.0.0.0:443")) { AddResultValue("IP:port=0.0.0.0:443 doesn't find. SslCertInfo=" + sslCertsStr); } if (!string.IsNullOrEmpty(thumbprint)) { if (!sslCertsStr.Contains(thumbprint.ToLower())) { AddResultValue("Certificate Hash=" + thumbprint + " doesn't find. SslCertInfo=" + sslCertsStr); } } else { AddResultValue("Thumbprint isn't defined"); } if (!sslCertsStr.Contains("{df179e9a-676b-4153-aa92-e589568c7d41}")) { AddResultValue("Application ID={df179e9a-676b-4153-aa92-e589568c7d41} doesn't find. SslCertInfo=" + sslCertsStr); } }
public static X509Certificate2 GetCertificate(StoreLocation storeLocation, string username, string templateNameRegex = null) { if (string.IsNullOrWhiteSpace(username)) { return(null); } string extractionRegex = null, nameMatchRegex = null; if (storeLocation == StoreLocation.LocalMachine) { extractionRegex = "DNS Name=([a-zA-Z0-9@\\.\\-_]+)"; nameMatchRegex = $"^{username}(.+)*"; } else { extractionRegex = "Principal Name=([a-zA-Z0-9@\\.\\-_]+)"; nameMatchRegex = $"^{username}(@.+)*"; } using (var store = new X509Store(StoreName.My, storeLocation)) { store.Open(OpenFlags.OpenExistingOnly); var candidateCertificates = store.Certificates.Find(X509FindType.FindBySubjectName, username, false) .Find(X509FindType.FindByExtension, DnsNameOid, false) .Find(X509FindType.FindByExtension, EnhancedKeyUsageOid, true); if (candidateCertificates.Count > 0) { foreach (var cert in candidateCertificates) { if (cert.Subject == cert.Issuer) { continue; } if (cert.Extensions[EnhancedKeyUsageOid] is X509EnhancedKeyUsageExtension eku && eku.EnhancedKeyUsages[ClientAuthenticationOid] == null) { continue; } var dnsNameExtension = cert.Extensions[DnsNameOid]; if (dnsNameExtension == null) { continue; } if (!string.IsNullOrWhiteSpace(templateNameRegex)) { var templateNameExtension = cert.Extensions[TemplateNameOid]; if (templateNameExtension == null) { continue; } var templateName = templateNameExtension.Format(false).Split('(').FirstOrDefault()?.Split('=').LastOrDefault()?.Trim(); if (string.IsNullOrWhiteSpace(templateName)) { continue; } if (!Regex.IsMatch(templateName, templateNameRegex, RegexOptions.IgnoreCase)) { continue; } } var nameToMatch = dnsNameExtension.Format(false); var nameMatches = Regex.Match(nameToMatch, extractionRegex); if (nameMatches != null || nameMatches.Groups.Count == 2 || Regex.IsMatch(nameMatches.Groups[1].Value, nameMatchRegex)) { return(cert); } } } return(null); } }
public IList <X509Certificate2> ListCertificates( CertificatePurpose purpose, StoreName storeName, StoreLocation location, bool isValid, bool requireExportable = true, DiagnosticInformation diagnostics = null) { diagnostics?.Debug($"Listing '{purpose.ToString()}' certificates on '{location}\\{storeName}'."); var certificates = new List <X509Certificate2>(); try { using (var store = new X509Store(storeName, location)) { store.Open(OpenFlags.ReadOnly); certificates.AddRange(store.Certificates.OfType <X509Certificate2>()); IEnumerable <X509Certificate2> matchingCertificates = certificates; switch (purpose) { case CertificatePurpose.All: matchingCertificates = matchingCertificates .Where(c => HasOid(c, AspNetHttpsOid)); break; case CertificatePurpose.HTTPS: matchingCertificates = matchingCertificates .Where(c => HasOid(c, AspNetHttpsOid)); break; default: break; } diagnostics?.Debug(diagnostics.DescribeCertificates(matchingCertificates)); if (isValid) { // Ensure the certificate hasn't expired, has a private key and its exportable // (for container/unix scenarios). diagnostics?.Debug("Checking certificates for validity."); var now = DateTimeOffset.Now; var validCertificates = matchingCertificates .Where(c => c.NotBefore <= now && now <= c.NotAfter && (!requireExportable || !RuntimeInformation.IsOSPlatform(OSPlatform.Windows) || IsExportable(c))) .ToArray(); var invalidCertificates = matchingCertificates.Except(validCertificates); diagnostics?.Debug("Listing valid certificates"); diagnostics?.Debug(diagnostics.DescribeCertificates(validCertificates)); diagnostics?.Debug("Listing invalid certificates"); diagnostics?.Debug(diagnostics.DescribeCertificates(invalidCertificates)); matchingCertificates = validCertificates; } // We need to enumerate the certificates early to prevent dispoisng issues. matchingCertificates = matchingCertificates.ToList(); var certificatesToDispose = certificates.Except(matchingCertificates); DisposeCertificates(certificatesToDispose); store.Close(); return((IList <X509Certificate2>)matchingCertificates); } } catch { DisposeCertificates(certificates); certificates.Clear(); return(certificates); } bool HasOid(X509Certificate2 certificate, string oid) => certificate.Extensions.OfType <X509Extension>() .Any(e => string.Equals(oid, e.Oid.Value, StringComparison.Ordinal)); #if !XPLAT bool IsExportable(X509Certificate2 c) => ((c.GetRSAPrivateKey() is RSACryptoServiceProvider rsaPrivateKey && rsaPrivateKey.CspKeyContainerInfo.Exportable) || (c.GetRSAPrivateKey() is RSACng cngPrivateKey && cngPrivateKey.Key.ExportPolicy == CngExportPolicies.AllowExport)); #else // Only check for RSA CryptoServiceProvider and do not fail in XPlat tooling as // System.Security.Cryptography.Cng is not part of the shared framework and we don't // want to bring the dependency in on CLI scenarios. This functionality will be used // on CLI scenarios as part of the first run experience, so checking the exportability // of the certificate is not important. bool IsExportable(X509Certificate2 c) => ((c.GetRSAPrivateKey() is RSACryptoServiceProvider rsaPrivateKey && rsaPrivateKey.CspKeyContainerInfo.Exportable) || !(c.GetRSAPrivateKey() is RSACryptoServiceProvider)); #endif }
public void ConfigureServices(IServiceCollection services) { var stsConfig = Configuration.GetSection("StsConfig"); var useLocalCertStore = Convert.ToBoolean(Configuration["UseLocalCertStore"]); var certificateThumbprint = Configuration["CertificateThumbprint"]; X509Certificate2 cert; if (_environment.IsProduction()) { if (useLocalCertStore) { using (X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine)) { store.Open(OpenFlags.ReadOnly); var certs = store.Certificates.Find(X509FindType.FindByThumbprint, certificateThumbprint, false); cert = certs[0]; store.Close(); } } else { // Azure deployment, will be used if deployed to Azure var vaultConfigSection = Configuration.GetSection("Vault"); var keyVaultService = new KeyVaultCertificateService(vaultConfigSection["Url"], vaultConfigSection["ClientId"], vaultConfigSection["ClientSecret"]); cert = keyVaultService.GetCertificateFromKeyVault(vaultConfigSection["CertificateName"]); } } else { cert = new X509Certificate2(Path.Combine(_environment.ContentRootPath, "damienbodserver.pfx"), ""); } services.AddDbContext <ApplicationDbContext>(options => options.UseSqlite(Configuration.GetConnectionString("DefaultConnection"))); services.Configure <StsConfig>(Configuration.GetSection("StsConfig")); services.Configure <EmailSettings>(Configuration.GetSection("EmailSettings")); services.AddSingleton <LocService>(); services.AddLocalization(options => options.ResourcesPath = "Resources"); services.AddAuthentication() .AddOpenIdConnect("aad", "Login with Azure AD", options => { options.Authority = $"https://login.microsoftonline.com/common"; options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = false }; options.ClientId = "99eb0b9d-ca40-476e-b5ac-6f4c32bfb530"; options.CallbackPath = "/signin-oidc"; }); services.AddIdentity <ApplicationUser, IdentityRole>() .AddEntityFrameworkStores <ApplicationDbContext>() .AddDefaultTokenProviders(); services.Configure <RequestLocalizationOptions>( options => { var supportedCultures = new List <CultureInfo> { new CultureInfo("en-US"), new CultureInfo("de-CH"), new CultureInfo("fr-CH"), new CultureInfo("it-CH") }; options.DefaultRequestCulture = new RequestCulture(culture: "de-CH", uiCulture: "de-CH"); options.SupportedCultures = supportedCultures; options.SupportedUICultures = supportedCultures; var providerQuery = new LocalizationQueryProvider { QureyParamterName = "ui_locales" }; options.RequestCultureProviders.Insert(0, providerQuery); }); services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1) .AddViewLocalization() .AddDataAnnotationsLocalization(options => { options.DataAnnotationLocalizerProvider = (type, factory) => { var assemblyName = new AssemblyName(typeof(SharedResource).GetTypeInfo().Assembly.FullName); return(factory.Create("SharedResource", assemblyName.Name)); }; }); services.AddTransient <IProfileService, IdentityWithAdditionalClaimsProfileService>(); services.AddTransient <IEmailSender, EmailSender>(); services.AddIdentityServer() .AddSigningCredential(cert) .AddInMemoryIdentityResources(Config.GetIdentityResources()) .AddInMemoryApiResources(Config.GetApiResources()) .AddInMemoryClients(Config.GetClients()) .AddAspNetIdentity <ApplicationUser>() .AddProfileService <IdentityWithAdditionalClaimsProfileService>(); }
/// <summary> /// Add custom signing certificate from certification store according thumbprint or from file /// </summary> /// <param name="builder"></param> /// <param name="configuration"></param> /// <returns></returns> public static IIdentityServerBuilder AddCustomSigningCredential(this IIdentityServerBuilder builder, IConfiguration configuration) { var certificateConfiguration = configuration.GetSection(nameof(CertificateConfiguration)).Get <CertificateConfiguration>(); if (certificateConfiguration.UseSigningCertificateThumbprint) { if (string.IsNullOrWhiteSpace(certificateConfiguration.SigningCertificateThumbprint)) { throw new Exception(SigningCertificateThumbprintNotFound); } StoreLocation storeLocation = StoreLocation.LocalMachine; bool validOnly = certificateConfiguration.CertificateValidOnly; // Parse the Certificate StoreLocation string certStoreLocationLower = certificateConfiguration.CertificateStoreLocation.ToLower(); if (certStoreLocationLower == StoreLocation.CurrentUser.ToString().ToLower() || certificateConfiguration.CertificateStoreLocation == ((int)StoreLocation.CurrentUser).ToString()) { storeLocation = StoreLocation.CurrentUser; } else if (certStoreLocationLower == StoreLocation.LocalMachine.ToString().ToLower() || certStoreLocationLower == ((int)StoreLocation.LocalMachine).ToString()) { storeLocation = StoreLocation.LocalMachine; } else { storeLocation = StoreLocation.LocalMachine; validOnly = true; } // Open Certificate var certStore = new X509Store(StoreName.My, storeLocation); certStore.Open(OpenFlags.ReadOnly); var certCollection = certStore.Certificates.Find(X509FindType.FindByThumbprint, certificateConfiguration.SigningCertificateThumbprint, validOnly); if (certCollection.Count == 0) { throw new Exception(CertificateNotFound); } var certificate = certCollection[0]; builder.AddSigningCredential(certificate); } else if (certificateConfiguration.UseSigningCertificatePfxFile) { if (string.IsNullOrWhiteSpace(certificateConfiguration.SigningCertificatePfxFilePath)) { throw new Exception(SigningCertificatePathIsNotSpecified); } if (File.Exists(certificateConfiguration.SigningCertificatePfxFilePath)) { try { builder.AddSigningCredential(new X509Certificate2(certificateConfiguration.SigningCertificatePfxFilePath, certificateConfiguration.SigningCertificatePfxFilePassword)); } catch (Exception e) { throw new Exception("There was an error adding the key file - during the creation of the signing key", e); } } else { throw new Exception($"Signing key file: {certificateConfiguration.SigningCertificatePfxFilePath} not found"); } } else if (certificateConfiguration.UseTemporarySigningKeyForDevelopment) { builder.AddDeveloperSigningCredential(); } else { throw new Exception("Signing credential is not specified"); } return(builder); }
public static X509Certificate2 GetCertificate() { Console.WriteLine("Store (empty line result in StoreName=My)."); Console.ForegroundColor = ConsoleColor.Gray; Console.WriteLine("[" + StoreName.My + "/" + StoreName.Root + "/" + StoreName.AddressBook + "/" + StoreName.CertificateAuthority + "]: "); Console.ForegroundColor = ConsoleColor.White; StoreName storeName = StoreName.My; string userFeedback; bool done = false; do { userFeedback = Console.ReadLine(); if (string.IsNullOrEmpty(userFeedback)) { // using the default values storeName = StoreName.My; done = true; } else { try { storeName = (StoreName)Enum.Parse(typeof(StoreName), userFeedback); done = true; } catch (Exception e) { Console.WriteLine(e); } } } while (!done); Console.WriteLine("Store Location (empty line result in StoreLocation=CurrentUser)."); Console.ForegroundColor = ConsoleColor.Gray; Console.WriteLine("[" + StoreLocation.CurrentUser + "/" + StoreLocation.LocalMachine + "]: "); Console.ForegroundColor = ConsoleColor.White; StoreLocation storeLocation = StoreLocation.CurrentUser; done = false; do { userFeedback = Console.ReadLine(); if (string.IsNullOrEmpty(userFeedback)) { // using the default values storeLocation = StoreLocation.CurrentUser; done = true; } else { try { storeLocation = (StoreLocation)Enum.Parse(typeof(StoreLocation), userFeedback); done = true; } catch (Exception e) { Console.WriteLine(e); } } } while (!done); X509Store certStore = new X509Store(storeName, storeLocation); certStore.Open(OpenFlags.ReadOnly); Console.WriteLine("At that location the following certificate exist: "); Console.WriteLine(" Serial"); Console.WriteLine(" Issuer"); Console.WriteLine(" Subject"); foreach (X509Certificate2 xxx in certStore.Certificates) { Console.ForegroundColor = ConsoleColor.Yellow; Console.WriteLine(" " + xxx.SerialNumber); Console.ForegroundColor = ConsoleColor.Gray; Console.WriteLine(" " + xxx.Issuer); Console.WriteLine(" " + xxx.Subject); //Console.WriteLine(); } Console.ForegroundColor = ConsoleColor.White; string defaultSerial = string.Empty; if (string.Equals(ConfigurationDocument.ConfigFilePath, "RaspConfiguration.Live.xml", StringComparison.OrdinalIgnoreCase)) { defaultSerial = "45A2F4A1"; } ////else if (string.Equals(ConfigurationDocument.ConfigFilePath, "RaspConfiguration.Test.xml", StringComparison.OrdinalIgnoreCase)) ////{ //// defaultSerial = "4037fb49"; ////} Console.Write("Serial number (empty line will result in " + defaultSerial + "): "); string serial = Console.ReadLine(); if (string.IsNullOrEmpty(serial)) { serial = defaultSerial; } X509Certificate2 clientCert = certStore.Certificates.Find(X509FindType.FindBySerialNumber, serial, true)[0]; certStore.Close(); return(clientCert); }
/// <summary> /// Helper function to look up and validate public keys for each recipient. /// </summary> /// <param name="message">An OpaqueMail.MailMessage that contains the message to send.</param> /// <param name="addressesWithPublicKeys">Collection containing recipients with valid public keys.</param> /// <param name="addressesNeedingPublicKeys">Collection containing recipients without valid public keys.</param> private void SmimeResolvePublicKeys(MailMessage message, out HashSet <string> addressesWithPublicKeys, out Dictionary <string, MailAddress> addressesNeedingPublicKeys) { // Initialize collections for all recipients. addressesWithPublicKeys = new HashSet <string>(); addressesNeedingPublicKeys = new Dictionary <string, MailAddress>(); MailAddressCollection[] addressRanges = new MailAddressCollection[] { message.To, message.CC, message.Bcc }; foreach (MailAddressCollection addressRange in addressRanges) { foreach (MailAddress toAddress in addressRange) { string canonicalToAddress = toAddress.Address.ToUpper(); if (SmimeCertificateCache.ContainsKey(canonicalToAddress)) { if (!addressesWithPublicKeys.Contains(canonicalToAddress)) { addressesWithPublicKeys.Add(canonicalToAddress); } } else { if (!addressesNeedingPublicKeys.ContainsKey(canonicalToAddress)) { addressesNeedingPublicKeys.Add(canonicalToAddress, toAddress); } } } } // If any addresses haven't been mapped to public keys, map them. if (addressesNeedingPublicKeys.Count > 0) { // Read from the Windows certificate store if valid certificates aren't specified. if (SmimeValidCertificates == null || SmimeValidCertificates.Count < 1) { // Load from the current user. X509Store store = new X509Store(StoreLocation.CurrentUser); store.Open(OpenFlags.OpenExistingOnly | OpenFlags.ReadOnly); SmimeValidCertificates = store.Certificates; store.Close(); // Add any tied to the local machine. store = new X509Store(StoreLocation.LocalMachine); store.Open(OpenFlags.OpenExistingOnly | OpenFlags.ReadOnly); SmimeValidCertificates.AddRange(store.Certificates); store.Close(); } // Loop through certificates and check for matching recipients. foreach (X509Certificate2 cert in SmimeValidCertificates) { // Look at certificates with email subject names. string canonicalCertSubject = ""; if (cert.Subject.StartsWith("E=")) { canonicalCertSubject = cert.Subject.Substring(2).ToUpper(); } else if (cert.Subject.StartsWith("CN=")) { canonicalCertSubject = cert.Subject.Substring(3).ToUpper(); } else { canonicalCertSubject = cert.Subject.ToUpper(); } int certSubjectComma = canonicalCertSubject.IndexOf(","); if (certSubjectComma > -1) { canonicalCertSubject = canonicalCertSubject.Substring(0, certSubjectComma); } // Only proceed if the key is for a recipient of this email. if (!addressesNeedingPublicKeys.ContainsKey(canonicalCertSubject)) { continue; } // Verify the certificate chain. if ((message.SmimeEncryptionOptionFlags & SmimeEncryptionOptionFlags.RequireCertificateVerification) > 0) { if (!cert.Verify()) { continue; } } // Ensure valid key usage scenarios. if ((message.SmimeEncryptionOptionFlags & SmimeEncryptionOptionFlags.RequireKeyUsageOfDataEncipherment) > 0 || (message.SmimeEncryptionOptionFlags & SmimeEncryptionOptionFlags.RequireEnhancedKeyUsageofSecureEmail) > 0) { bool keyDataEncipherment = false, enhancedKeySecureEmail = false; foreach (X509Extension extension in cert.Extensions) { if (!keyDataEncipherment && extension.Oid.FriendlyName == "Key Usage") { X509KeyUsageExtension ext = (X509KeyUsageExtension)extension; if ((ext.KeyUsages & X509KeyUsageFlags.DataEncipherment) != X509KeyUsageFlags.None) { keyDataEncipherment = true; if (!((message.SmimeEncryptionOptionFlags & SmimeEncryptionOptionFlags.RequireEnhancedKeyUsageofSecureEmail) > 0)) { break; } } } if (!enhancedKeySecureEmail && extension.Oid.FriendlyName == "Enhanced Key Usage") { X509EnhancedKeyUsageExtension ext = (X509EnhancedKeyUsageExtension)extension; OidCollection oids = ext.EnhancedKeyUsages; foreach (Oid oid in oids) { if (oid.FriendlyName == "Secure Email") { enhancedKeySecureEmail = true; break; } } } } if ((message.SmimeEncryptionOptionFlags & SmimeEncryptionOptionFlags.RequireKeyUsageOfDataEncipherment) > 0 && !keyDataEncipherment) { continue; } if ((message.SmimeEncryptionOptionFlags & SmimeEncryptionOptionFlags.RequireEnhancedKeyUsageofSecureEmail) > 0 && !enhancedKeySecureEmail) { continue; } } // If we've made it this far, we can use the certificate for a recipient. MailAddress originalAddress = addressesNeedingPublicKeys[canonicalCertSubject]; SmimeCertificateCache.Add(canonicalCertSubject, cert); addressesWithPublicKeys.Add(canonicalCertSubject); addressesNeedingPublicKeys.Remove(canonicalCertSubject); // Shortcut to abort processing of additional certificates if all recipients are accounted for. if (addressesNeedingPublicKeys.Count < 1) { break; } } } }
internal static List <X509Certificate2> FindCandidates( X509Certificate2 leaf, X509Certificate2Collection extraStore, List <X509Certificate2> downloaded, List <X509Certificate2> systemTrusted, ref TimeSpan remainingDownloadTime) { List <X509Certificate2> candidates = new List <X509Certificate2>(); Queue <X509Certificate2> toProcess = new Queue <X509Certificate2>(); toProcess.Enqueue(leaf); using (var systemRootStore = new X509Store(StoreName.Root, StoreLocation.LocalMachine)) using (var systemIntermediateStore = new X509Store(StoreName.CertificateAuthority, StoreLocation.LocalMachine)) using (var userRootStore = new X509Store(StoreName.Root, StoreLocation.CurrentUser)) using (var userIntermediateStore = new X509Store(StoreName.CertificateAuthority, StoreLocation.CurrentUser)) { systemRootStore.Open(OpenFlags.ReadOnly); systemIntermediateStore.Open(OpenFlags.ReadOnly); userRootStore.Open(OpenFlags.ReadOnly); userIntermediateStore.Open(OpenFlags.ReadOnly); X509Certificate2Collection systemRootCerts = systemRootStore.Certificates; X509Certificate2Collection systemIntermediateCerts = systemIntermediateStore.Certificates; X509Certificate2Collection userRootCerts = userRootStore.Certificates; X509Certificate2Collection userIntermediateCerts = userIntermediateStore.Certificates; // fill the system trusted collection foreach (X509Certificate2 systemRootCert in systemRootCerts) { systemTrusted.Add(systemRootCert); } foreach (X509Certificate2 userRootCert in userRootCerts) { systemTrusted.Add(userRootCert); } X509Certificate2Collection[] storesToCheck = { extraStore, userIntermediateCerts, systemIntermediateCerts, userRootCerts, systemRootCerts, }; while (toProcess.Count > 0) { X509Certificate2 current = toProcess.Dequeue(); if (!candidates.Contains(current)) { candidates.Add(current); } List <X509Certificate2> results = FindIssuer( current, storesToCheck, downloaded, ref remainingDownloadTime); if (results != null) { foreach (X509Certificate2 result in results) { if (!candidates.Contains(result)) { toProcess.Enqueue(result); } } } } } return(candidates); }
private static void AddX509Names(SafeX509NameStackHandle nameStack, StoreLocation storeLocation, HashSet<string> issuerNameHashSet) { using (var store = new X509Store(StoreName.Root, storeLocation)) { store.Open(OpenFlags.ReadOnly); foreach (var certificate in store.Certificates) { //Check if issuer name is already present //Avoiding duplicate names if (!issuerNameHashSet.Add(certificate.Issuer)) { continue; } using (SafeX509Handle certHandle = Crypto.X509Duplicate(certificate.Handle)) { using (SafeX509NameHandle nameHandle = Crypto.DuplicateX509Name(Crypto.X509GetIssuerName(certHandle))) { if (Crypto.PushX509NameStackField(nameStack, nameHandle)) { // The handle ownership has been transferred into the STACK_OF(X509_NAME). nameHandle.SetHandleAsInvalid(); } else { throw new CryptographicException(SR.net_ssl_x509Name_push_failed_error); } } } } } }
/// <summary> /// Create the actual certificate /// </summary> public static bool CreateCertificate(ICertificateSettings settings, Action <string> log, out string thumbprint, out string errorMessage) { errorMessage = string.Empty; thumbprint = string.Empty; try { var keyStore = new Pkcs12Store(); log(Strings.GeneratingKeys); var pGen = new RsaKeyPairGenerator(); var genParam = new RsaKeyGenerationParameters( BigInteger.ValueOf(0x10001), new SecureRandom(), 1024, 10); pGen.Init(genParam); var keyPair = pGen.GenerateKeyPair(); log(Strings.GeneratingCertificate); var attrs = new Dictionary <DerObjectIdentifier, string>(); var oids = new List <DerObjectIdentifier> { X509Name.O, X509Name.L, X509Name.C, X509Name.CN, X509Name.EmailAddress, X509Name.OU, X509Name.ST }; oids.Reverse(); if (!string.IsNullOrEmpty(settings.OrgName)) { attrs.Add(X509Name.O, settings.OrgName); } else { oids.Remove(X509Name.O); } if (!string.IsNullOrEmpty(settings.OrgUnit)) { attrs.Add(X509Name.OU, settings.OrgUnit); } else { oids.Remove(X509Name.OU); } if (!string.IsNullOrEmpty(settings.City)) { attrs.Add(X509Name.L, settings.City); } else { oids.Remove(X509Name.L); } if (!string.IsNullOrEmpty(settings.CountryCode)) { attrs.Add(X509Name.C, settings.CountryCode); } else { oids.Remove(X509Name.C); } if (!string.IsNullOrEmpty(settings.State)) { attrs.Add(X509Name.ST, settings.State); } else { oids.Remove(X509Name.ST); } if (!string.IsNullOrEmpty(settings.Email)) { attrs.Add(X509Name.EmailAddress, settings.Email); } else { oids.Remove(X509Name.EmailAddress); } if (!string.IsNullOrEmpty(settings.UserName)) { attrs.Add(X509Name.CN, settings.UserName); } else { oids.Remove(X509Name.CN); } var certGen = new X509V3CertificateGenerator(); var random = new SecureRandom(); certGen.SetSerialNumber(BigInteger.ValueOf(Math.Abs(random.NextInt()))); certGen.SetIssuerDN(new X509Name(oids, attrs)); certGen.SetNotBefore(DateTime.Today.Subtract(new TimeSpan(1, 0, 0, 0))); var years = Math.Min(settings.MaxYears, 50); certGen.SetNotAfter(DateTime.Today.AddYears(years)); certGen.SetSubjectDN(new X509Name(oids, attrs)); certGen.SetPublicKey(keyPair.Public); certGen.SetSignatureAlgorithm("SHA1WithRSAEncryption"); var cert = certGen.Generate(keyPair.Private); // Save log(Strings.SavingCertificate); var keyEntry = new AsymmetricKeyEntry(keyPair.Private); var certEntry = new X509CertificateEntry(cert); const string alias = "alias"; keyStore.SetKeyEntry(alias, keyEntry, new[] { certEntry }); var password = settings.Password; var memoryStream = new MemoryStream(); keyStore.Save(memoryStream, password.ToCharArray(), random); memoryStream.Position = 0; // Save certificate var path = settings.Path; var folder = Path.GetDirectoryName(path); if (!string.IsNullOrEmpty(folder)) { Directory.CreateDirectory(folder); } // Set path in finished page. using (var fileStream = new FileStream(path, FileMode.Create, FileAccess.Write)) { memoryStream.WriteTo(fileStream); } if (settings.ImportInCertificateStore) { log("Importing certificate in My Certificates store"); var certificate = new X509Certificate2(path, password, X509KeyStorageFlags.Exportable | X509KeyStorageFlags.PersistKeySet); thumbprint = certificate.Thumbprint; var x509Store2 = new X509Store(StoreName.My, StoreLocation.CurrentUser); try { x509Store2.Open(OpenFlags.ReadWrite); x509Store2.Add(certificate); x509Store2.Close(); } catch (Exception ex) { errorMessage = string.Format("Failed to import certificate because: {0}", ex.Message); return(false); } } if (years < 30) { log("Certificate is intended for evaluation purposes. It cannot be used to deploy to the market."); } return(true); } catch (Exception ex) { ErrorLog.DumpError(ex); errorMessage = string.Format("Failed to create certificate because {0}.", ex.Message); return(false); } }
public static void X509Cert2ToStringVerbose() { X509Store store = new X509Store("My", StoreLocation.CurrentUser); store.Open(OpenFlags.ReadOnly); foreach (X509Certificate2 c in store.Certificates) { Assert.False(string.IsNullOrWhiteSpace(c.ToString(true))); } }
/// <summary> /// Initializes a new instance of the <see cref="MimeKit.Cryptography.WindowsSecureMimeContext"/> class. /// </summary> public WindowsSecureMimeContext() { CertificateStore = new X509Store(StoreName.My, StoreLocation.CurrentUser); CertificateStore.Open(OpenFlags.ReadWrite); }