Exemple #1
0
        /// <summary>
        /// Uses the <see cref="RsaSecurityKey"/>s stored in the given directory.
        /// Note: this extension will automatically ignore incompatible keys and
        /// create a new RSA key if none has been previously added.
        /// </summary>
        /// <param name="configuration">The options used to configure the OpenID Connect server.</param>
        /// <param name="directory">The directory containing the encrypted keys.</param>
        /// <param name="protector">The data protector used to decrypt the key.</param>
        /// <returns>The options used to configure the OpenID Connect server.</returns>
        public static OpenIdConnectServerConfiguration UseKeys(
            [NotNull] this OpenIdConnectServerConfiguration configuration,
            [NotNull] DirectoryInfo directory, [NotNull] IDataProtector protector)
        {
            if (!directory.Exists)
            {
                throw new InvalidOperationException("The directory does not exist");
            }

            foreach (var file in directory.EnumerateFiles("*.key"))
            {
                using (var buffer = new MemoryStream())
                    using (var stream = file.Open(FileMode.Open)) {
                        // Copy the key content to the buffer.
                        stream.CopyTo(buffer);

                        // Extract the key material using the data protector.
                        // Ignore the key if the decryption process failed.
                        var parameters = protector.DecryptKey(buffer.ToArray());
                        if (parameters == null)
                        {
                            continue;
                        }

                        configuration.UseKey(new RsaSecurityKey(parameters.Value));
                    }
            }

            // If no signing key has been found,
            // generate and persist a new RSA key.
            if (configuration.Options.SigningCredentials.Count == 0)
            {
                // Generate a new 2048 bit RSA key and export its public/private parameters.
                var provider   = new RSACryptoServiceProvider(2048);
                var parameters = provider.ExportParameters(includePrivateParameters: true);

                // Generate a new file name for the key and determine its absolute path.
                var path = Path.Combine(directory.FullName, Guid.NewGuid().ToString() + ".key");

                using (var stream = new FileStream(path, FileMode.CreateNew, FileAccess.Write)) {
                    // Encrypt the key using the data protector.
                    var bytes = protector.EncryptKey(parameters);

                    // Write the encrypted key to the file stream.
                    stream.Write(bytes, 0, bytes.Length);
                }

                configuration.UseKey(new RsaSecurityKey(parameters));
            }

            return(configuration);
        }