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();
                }
            }
        }
Example #2
0
        /// <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;
            }
        }
Example #3
0
 public static void OpenNotExistant()
 {
     using (X509Store store = new X509Store(Guid.NewGuid().ToString("N"), StoreLocation.CurrentUser))
     {
         Assert.ThrowsAny<CryptographicException>(() => store.Open(OpenFlags.OpenExistingOnly));
     }
 }
Example #4
0
        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);
                        }
                    }
                }
            }
        }
Example #5
0
        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));
                }
            }
        }
Example #6
0
 public static void OpenMyStore()
 {
     using (X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser))
     {
         store.Open(OpenFlags.ReadOnly);
     }
 }
Example #7
0
 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));
        }
Example #10
0
        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;
        }
Example #13
0
        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);
            }
        }
Example #14
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();
            }
        }
Example #20
0
 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();
     }
 }
Example #21
0
        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 ; 
		}
Example #23
0
    //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.");
        }
    }
Example #24
0
        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();
            }
        }
Example #26
0
        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;
        }
Example #27
0
        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",
                });
            });
        }
Example #28
0
        // 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);
        }
Example #29
0
        /// <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();
                });
            });
        }
Example #30
0
        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);
            }
        }
Example #31
0
        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)
                }));
            }
        }
Example #33
0
        // 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();
        }
Example #35
0
        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);
        }
Example #36
0
        /// <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);
            }
        }
Example #37
0
        /// <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;
        }
Example #38
0
        /// <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;
            }
        }
Example #39
0
        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>());
            }
        }
Example #40
0
        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;
        }
Example #41
0
        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);
            }
        }
Example #43
0
        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);
        }
Example #46
0
        /// <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"));
            }
        }
Example #47
0
        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();
        }
Example #48
0
        /// <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);
        }
Example #49
0
        /// <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);
            }
        }
Example #50
0
        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);
            }
        }
Example #51
0
        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
        }
Example #52
0
        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);
        }
Example #54
0
        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);
        }
Example #55
0
        /// <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);
        }
Example #57
0
        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);
                            }
                        }
                    }
                }
            }
        }
Example #58
0
        /// <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);
            }
        }
Example #59
0
        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)));
            }
        }
Example #60
0
 /// <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);
 }