Convert CodeFluent.Runtime.Utilities.Authenticode.FindSuitableCertificate to C# - certificate

I'm trying to convert Dim certificate As X509Certificate2 = CodeFluent.Runtime.Utilities.Authenticode.FindSuitableCertificate() from VB.Net to C# and I know that it's X509Certificate2 AuthenticodeCert = CodeFluent.Runtime.Utilities.Authenticode.FindSuitableCertificate();
The problem is that in C# it produces a ArgumentNullException, but works in VB.Net.
X509Certificate2 AuthenticodeCert = Authenticode.FindSuitableCertificate(); // Problem
// Check if there is a Certificate in the Certificate Store that can signs code.
if (Authenticode.CanSignCode(AuthenticodeCert) == true) // Problem ArgumentNullException
{// Bla, Bla}
Any help would be Appreciated. Thanks.

I figured it out.
X509Certificate2 AuthenticodeCert = new X509Certificate2("PFX_Private_Key", "Password");
The only problem is if it returns null then I hit an error. The only remedying it seems for that was to Try Catch. Anyone know a better way to code for the null value?
Thanks.

The CodeFluent.Runtime library is a .Net framework library independant of the calling language. It is itself implemented in C# .
So I suspect your issue is not related to the language you use, but the local machine certificate stores or the executing user that are different.
The default FindSuitableCertificate looks into the My certificate store for Current User.
There is another more advanced signature you can use if the signing certificate installed on the machine is installed somewhere else instead :
/// <summary>
/// Finds a suitable certificate for authenticode signing.
/// </summary>
/// <param name="storeName">The store name.</param>
/// <param name="storeLocation">The store location.</param>
/// <param name="thumbPrint">The optional thumbprint. May be null.</param>
/// <returns>A certificate instance or null if not found.</returns>
public static X509Certificate2 FindSuitableCertificate(StoreName storeName, StoreLocation storeLocation, string thumbPrint)

Related

How do you set permissions on a certificate in the Windows Certificate Store through PowerShell 7?

Every resource I've found so far, such as this question, boils down to:
Get the certificate as an X509Certificate2
Cast the PrivateKey property to RSACryptoServiceProvider
Do stuff involving CspKeyContainerInfo property on the private key
This works in PowerShell 5, but in PowerShell 7, the PrivateKey property is an RSACng, not an RSACryptoServiceProvider, and so step 2 doesn't work.
FYI, PrivateKey was deprecated. You are now required to use the GetRSAPrivateKey extension method.
I cannot find any documentation, but it appears that .Net Framework used to return an RSA that also implemented RSACryptoServiceProvider which is where we could get the CspKeyContainerInfo, but now we are required to grab the key RSA derived type RSACng which is returned by the extension method. From here you can grab properties like the $cert.Key.UniqueName

.Net Core 2.0 Web API using JWT - Adding Identity breaks the JWT authentication

(Edit - Found proper fix! see below)
OK - this is my first attempt at .Net Core 2.0 and authentication, though I've done things with Web API 2.0 in the past, and have worked fairly extensively on various MVC and Webforms ASP projects over the last couple of years.
I'm trying to create a Web API ONLY project using .Net Core. This will form the back end of a multi-tenant application for producing some reports, so I need to be able to authenticate users. It seems the usual approach is to use JWT - first authenticate the user to generate a token, then pass that to the client to use on every API request. Data will be stored and retrieved using EF Core.
I followed this post for a basic way to get this set up, and I managed to get this to work ok - I have a controller which accepts a username/password and returns a token if valid, and some Authorization policies set up based on the claims.
The next thing I need is to actually manage the users/passwords/etc. I thought I'd just use .Net Core Identity for this as that way I would have lots of ready-made code for worry about users/roles, passwords etc. I was using custom User class and UserRole classes which derived from the standard IdentityUser and IdentityRole classes, but I've since reverted to the standard ones now.
The problem I have is that I can't quite figure out how to add identity & register all the various Services (rolemanager, usermanager, etc) without also breaking the authentication - basically as soon as I add this line to my Startup.ConfigureServices class:
services.AddIdentity<IdentityUser, IdentityRole>()
.AddEntityFrameworkStores<MyContext>();
It all goes wrong, and I can no longer see any claims when I receive a request, so all the policies just lock down and you can't get to anything.
If I don't have those lines, then I end up with errors related to UserManager, RoleManager, UserStore etc. all not being registered for DI.
So... how (if it's possible) can I register Identity and hook it up to the Context correctly, but avoid/Remove any changes to the actual Authorisation mechanism?
I've looked around a fair bit online, but a lot of this has changed since .Net Core 1.x so a lot of the tutorials etc. aren't really valid any more.
I'm not intending this API application to have any front-end code, so I don't need any cookie authentication for forms or anything for now.
Edit
ok, I've now found that in this code setting up the JWT authentication in the Startup.ConfigureServices() method:
services.AddAuthentication(
JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
>>breakpoint>>> options.TokenValidationParameters =
new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = "Blah.Blah.Bearer",
ValidAudience = "Blah.Blah.Bearer",
IssuerSigningKey =
JwtSecurityKey.Create("verylongsecretkey")
};
});
If I put a breakpoint at the line indicated (via ">>breakpoint>>>") then it gets hit when I don't add the lines to add identity services, but if I do add those lines then it never gets hit. This is true no matter where in the method I put the services.AddIdentity() call. I get that this is simply a lambda so it's getting executed at a later point, but is there any way I can get the AddIdentity stuff to NOT set up Authentication, or make the code immediately remove it? I assume at some point there's some code which elects to not run the Lambda for config I've set there as the Identity stuff has already set it...
Thanks for reading all that if you have :)
EDIT - Found an answer
ok, I eventually found this GH issue which is basically exactly this problem:
https://github.com/aspnet/Identity/issues/1376
Basically what I had to do was twofold:
Ensure that the call to services.AddIdentity<IdentityUser, IdentityContext() was made first
Change the call to add auth from:
services.AddAuthentication(
JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
...
To:
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
...
This does annoyingly result in a cookie being created, but this isn't then used for authentication as far as I can tell - it's purely using the bearer token on requests to controllers/actions which have [Authorize(Policy = "Administrator")] or similar set at least.
I need to test more, and I'll try to come back here an update this if I find it is not working in some way.
(Edited - put proper solution in as an answer now)
I eventually put together the solution, so on the suggestion of user alwayslearning I've edited my post and I'm putting this in as an actual answer.
ok, This can be done properly. First, you need to use the Authentication options I pointed out in my edit above - that's fine.
Then you need to useservices.AddIdentityCore<TUser>() rather than services.AddIdentity<TUser>(). This however, doesn't add a whole bunch of things for role management, and is apparently lacking the proper constructor to give it the type of Role you want to use. This means that in my case I had to do this:
IdentityBuilder builder = services.AddIdentityCore<IdentityUser>(opt =>
{
opt.Password.RequireDigit = true;
opt.Password.RequiredLength = 8;
opt.Password.RequireNonAlphanumeric = false;
opt.Password.RequireUppercase = true;
opt.Password.RequireLowercase = true;
}
);
builder = new IdentityBuilder(builder.UserType, typeof(IdentityRole), builder.Services);
builder
.AddEntityFrameworkStores<MyContext>();
//.AddDefaultTokenProviders();
builder.AddRoleValidator<RoleValidator<IdentityRole>>();
builder.AddRoleManager<RoleManager<IdentityRole>>();
builder.AddSignInManager<SignInManager<IdentityUser>>();
Having done that, the next thing is to make sure that when validating a user login (prior to sending a token), you make sure to use the SignInManager method CheckPasswordSignInAsync and not PasswordSignInAsync:
public async Task<IdentityUser> GetUserForLogin(string userName, string password)
{
//find user first...
var user = await _userManager.FindByNameAsync(userName);
if (user == null)
{
return null;
}
//validate password...
var signInResult = await _signInManager.CheckPasswordSignInAsync(user, password, false);
//if password was ok, return this user.
if (signInResult.Succeeded)
{
return user;
}
return null;
}
if you use the PasswordSignInAsync method then you'll get a runtime error re. No IAuthenticationSignInHandler being configured.
I hope this helps someone at some point.
I have extracted the AddIdentity code from github and created an extension method based on it that doesn't add the default Cookie Authenticator, It's now pretty similar to the built in AddIdentityCore but can accept IdentityRole.
/// <summary>
/// Contains extension methods to <see cref="IServiceCollection"/> for configuring identity services.
/// </summary>
public static class IdentityServiceExtensions
{
/// <summary>
/// Adds the default identity system configuration for the specified User and Role types. (Without Authentication Scheme)
/// </summary>
/// <typeparam name="TUser">The type representing a User in the system.</typeparam>
/// <typeparam name="TRole">The type representing a Role in the system.</typeparam>
/// <param name="services">The services available in the application.</param>
/// <returns>An <see cref="IdentityBuilder"/> for creating and configuring the identity system.</returns>
public static IdentityBuilder AddIdentityWithoutAuthenticator<TUser, TRole>(this IServiceCollection services)
where TUser : class
where TRole : class
=> services.AddIdentityWithoutAuthenticator<TUser, TRole>(setupAction: null);
/// <summary>
/// Adds and configures the identity system for the specified User and Role types. (Without Authentication Scheme)
/// </summary>
/// <typeparam name="TUser">The type representing a User in the system.</typeparam>
/// <typeparam name="TRole">The type representing a Role in the system.</typeparam>
/// <param name="services">The services available in the application.</param>
/// <param name="setupAction">An action to configure the <see cref="IdentityOptions"/>.</param>
/// <returns>An <see cref="IdentityBuilder"/> for creating and configuring the identity system.</returns>
public static IdentityBuilder AddIdentityWithoutAuthenticator<TUser, TRole>(this IServiceCollection services, Action<IdentityOptions> setupAction)
where TUser : class
where TRole : class
{
// Hosting doesn't add IHttpContextAccessor by default
services.AddHttpContextAccessor();
// Identity services
services.TryAddScoped<IUserValidator<TUser>, UserValidator<TUser>>();
services.TryAddScoped<IPasswordValidator<TUser>, PasswordValidator<TUser>>();
services.TryAddScoped<IPasswordHasher<TUser>, PasswordHasher<TUser>>();
services.TryAddScoped<ILookupNormalizer, UpperInvariantLookupNormalizer>();
services.TryAddScoped<IRoleValidator<TRole>, RoleValidator<TRole>>();
// No interface for the error describer so we can add errors without rev'ing the interface
services.TryAddScoped<IdentityErrorDescriber>();
services.TryAddScoped<ISecurityStampValidator, SecurityStampValidator<TUser>>();
services.TryAddScoped<ITwoFactorSecurityStampValidator, TwoFactorSecurityStampValidator<TUser>>();
services.TryAddScoped<IUserClaimsPrincipalFactory<TUser>, UserClaimsPrincipalFactory<TUser, TRole>>();
services.TryAddScoped<UserManager<TUser>>();
services.TryAddScoped<SignInManager<TUser>>();
services.TryAddScoped<RoleManager<TRole>>();
if (setupAction != null)
{
services.Configure(setupAction);
}
return new IdentityBuilder(typeof(TUser), typeof(TRole), services);
}
}
Now you can use the above code normally from a WebApi project like so
.AddIdentityWithoutAuthenticator<User, IdentityRole>()

Determine certificate key type (RSA vs EC) in .NET or BouncyCastle?

Currently we have a routine that Signs a byte[] given a certificate (and it's private key). However, the type of certificate/keys is hardcoded as "Certificate with RSA keys". That code is :
public byte[] Sign(byte[] bytesToSign, bool fOAEP, X509Certificate2 certificate)
{
using (RSACryptoServiceProvider provider = new RSACryptoServiceProvider())
{
// HACK: Round-trip the key to XML and back, to get provider type working
// as 'Microsoft Enhanced RSA and AES Cryptographic Provider' (for
// SHA256/SHA512 signing hash) instead of 'Microsoft Enhanced
// Cryptographic Provider v1.0' (that limits us to SHA1)
string publicKeyXml = certificate.PrivateKey.ToXmlString(true);
provider.FromXmlString(publicKeyXml);
// We use the private key to sign.
return provider.SignData(bytesToSign, CryptoConfig.MapNameToOID("SHA512"));
}
}
We would like to make it more flexible where if the certificate uses RSA keys, we process it one way but if it uses EC keys, then we process it differently. Basically the Crypto Service Provider type would be of a different type.
So the core question is:
Given a certificate with public+private keys (for signing) OR a certificate with just public keys (for verifying), how do you determine the types of keys used by the certificate?
I'm open to standard .NET libs or even BouncyCastle.Org libs.
You can check key type (algorithm) via certificate.PublicKey.Oid.
Here you can see supported by Microsoft OIDs: http://msdn.microsoft.com/en-us/library/ff635835.aspx
Other OIDs can be checked at oid-info.com

How to configure ProviderManifestToken for EF Code First

I have a asp.net MVC3 project using EF code-first. For my unit testing I have been using SQL Server CE 4.0 and SQL Server 2008 Express. Both have worked perfectly with EF generating my database as expected.
However, when I run my application outside of a unit test and point it at my connection strings I get the error
ProviderIncompatibleException: The provider did not return a ProviderManifestToken string
I have read the MS documentation on this and it appears this is a SqlVersion token that the EF model generates. The problem is that I am using the code first approach so I have no .edmx file nor do I know where to point my metadata info to because the db hasn't been generated yet.
I know my connection strings as far as db name, username, and pass are correct because changing them to wrong values throws the expected error. Not sure where to begin.
Thanks.
Here is my connection string:
<connectionStrings>
<add
name="SqlConnection"
providerName="System.Data.SqlClient"
connectionString="Data Source=WORKSTATION\SQLEXPRESS;Initial Catalog=CodeFirst;Integrated Security=False;
Persist Security Info=False;User ID=CodeFirst_user;Password=password1;Connect Timeout=120;MultipleActiveResultSets=True;"/>
</connectionStrings>
If you're using EF 6 (just released) you have an alternative.
Dependency Resolution
You can use the new dependency resolution feature to register an implementation of IManifestTokenResolver (described in this preview documentation as IManifestTokenService).
This article gives a bit more information on how to use DbConfiguration. The easiest way to use it is like this:
DbConfigurationType(typeof(EntityFrameworkDbConfiguration))]
public class MyContextContext : DbContext
{
}
This example avoids any trip to the database when building the metadata for SQL Server connections, and automatically specifies SQL Server 2005 compatability.
using System.Data.Common;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Data.Entity.Infrastructure.DependencyResolution;
using System.Data.SqlClient;
/// <summary>
/// A configuration class for SQL Server that specifies SQL 2005 compatability.
/// </summary>
internal sealed class EntityFrameworkDbConfiguration : DbConfiguration
{
/// <summary>
/// The provider manifest token to use for SQL Server.
/// </summary>
private const string SqlServerManifestToken = #"2005";
/// <summary>
/// Initializes a new instance of the <see cref="EntityFrameworkDbConfiguration"/> class.
/// </summary>
public EntityFrameworkDbConfiguration()
{
this.AddDependencyResolver(new SingletonDependencyResolver<IManifestTokenResolver>(new ManifestTokenService()));
}
/// <inheritdoc />
private sealed class ManifestTokenService : IManifestTokenResolver
{
/// <summary>
/// The default token resolver.
/// </summary>
private static readonly IManifestTokenResolver DefaultManifestTokenResolver = new DefaultManifestTokenResolver();
/// <inheritdoc />
public string ResolveManifestToken(DbConnection connection)
{
if (connection is SqlConnection)
{
return SqlServerManifestToken;
}
return DefaultManifestTokenResolver.ResolveManifestToken(connection);
}
}
}
After hours of searching & fiddling, I found a way to do it. Turns out the DbModelBuilder class takes a DbProviderInfo in its Build method, so I use that instead of relying on EF to call OnModelCreated:
// 'Entities' is my DbContext subclass, the "container" in EF terms.
public static Entities GetNewContext()
{
// Get a connection, for example:
var connection = new SqlConnection(GetConnectionString());
// Create a DbModelBuilder
var modelBuilder = new DbModelBuilder();
// Configure the model builder.
// I changed my DbContext subclass - added a public version of OnModelCreated and called it ConfigureModelBuilder
Entities.ConfigureModelBuilder(modelBuilder);
// Here's where the magic happens.
// Build the model and pass the ProviderManifestToken (I use 2005 to avoid a bug in precision of sql datetime columns when using concurrency control)
var model = modelBuilder.Build(new System.Data.Entity.Infrastructure.DbProviderInfo("System.Data.SqlClient", "2005"));
// Compile the model
var compiledModel = model.Compile();
// Create the container (DbContext subclass). Ideally all the previous stuff should be cached.
return new Entities(connection, compiledModel, true);
}
Obviously this needs some reorganization (e.g. cache the compiled model so you don't need to re-build it every time a context is created).
For me this completely solved the problem. Enjoy!
I just had this exact problem but I traced it down to my SQL Server service wasn't running. I had just restarted my computer and usually it starts on it's own but didn't for some reason.
In my case, my connection string name must match the context class name.
Connection String:
<connectionStrings>
<add name="NunuContext" connectionString="Data Source=|DataDirectory|Nunu.sdf" providerName="System.Data.SqlServerCe.4.0" />
</connectionStrings>
Context Class:
using System.Data.Entity;
namespace Nunu.Models
{
public class NunuContext : DbContext
{
System.Data.Entity.DropCreateDatabaseIfModelChanges<Nunu.Models.NunuContext>());
public DbSet<Nunu.Models.NunuFirst> NunuFirsts { get; set; }
public DbSet<Nunu.Models.NunuLast> NunuLasts { get; set; }
}
}
I found, when i provided explicit "User Id=abcUser; Password=somePwd;" in my connection string i am able to resolve the same error. Earlier i was using the "Trusted_Connection=true;", which allowed me to debug my web project, but started giving me error - {"The provider did not return a ProviderManifestToken string."} as soon as i added the Windows azure project and tried debugging the Azure project after adding my web project as a web role under it.
Hope it helps some one experiencing a similar situation.
Thanks,
Vivek Bahl
Changing to Data Source=localhost worked for me also using MS SQL 2008 R2 Express
Changing the Data Source to localhost in the connectionString solved my problem.
I had this problem when working through the MVC3 tutorial on ASP.NET.
My solution ended up being to use (localhost) instead of a named Data Source. This works fine on my box, for local dev work, but wouldn't help if the database were on a separate server.
I see some comments about oracle above, so here's the code for "EntityFrameworkDbConfiguration" adjusted for oracle:
internal sealed class EntityFrameworkDbConfiguration : DbConfiguration
{
/// <summary>
/// Initializes a new instance of the <see cref="EntityFrameworkDbConfiguration"/> class.
/// </summary>
public EntityFrameworkDbConfiguration()
{
this.AddDependencyResolver(Oracle.ManagedDataAccess.EntityFramework.EFOracleProviderServices.Instance);
}
}
This has proven helpful for me:
<connectionString="Data Source=WORKSTATION\SQLEXPRESS;Initial Catalog=CodeFirst;User ID=CodeFirst_user;Password=********"/>
</connectionStrings>

How can I prevent unauthorized code from accessing my assembly in .NET 2.0?

In .NET 1.x, you could use the StrongNameIdentityPermissionAttribute on your assembly to ensure that only code signed by you could access your assembly. According to the MSDN documentation,
In the .NET Framework version 2.0 and later, demands for identity
permissions are ineffective if the calling assembly has full trust.
This means that any application with full trust can just bypass my security demands.
How can I prevent unauthorized code from accessing my assembly in .NET 2.0?
As per Eric's suggestion, I solved it by checking the key myself. In the code I want to protect, I add the following call,
EnsureAssemblyIsSignedByMyCompany( Assembly.GetCallingAssembly() );
Then the implementation of that method is
/// <summary>
/// Ensures that the given assembly is signed by My Company or Microsoft.
/// </summary>
/// <param name="assembly"></param>
private static void EnsureAssemblyIsSignedByMyCompany( Assembly assembly )
{
if ( assembly == null )
throw new ArgumentNullException( "assembly" );
byte[] pubkey = assembly.GetName().GetPublicKeyToken();
if ( pubkey.Length == 0 )
throw new ArgumentException( "No public key token in assembly." );
StringBuilder builder = new StringBuilder();
foreach ( byte b in pubkey )
{
builder.AppendFormat( "{0:x2}", b );
}
string pkString = builder.ToString();
if ( pkString != "b77a5c561934e089" /* Microsoft */ &&
pkString != "abababababababab" /* Ivara */ )
{
throw new ArgumentException( "Assembly is not signed by My Company or Microsoft. You do not have permission to call this code." );
}
}
** Names and keys changed to protect the innocent. Any likeness to real names or companies is merely a coincidence.*
See this article:
http://blogs.msdn.com/ericlippert/archive/2008/10/06/preventing-third-party-derivation-part-two.aspx
Particularly this part:
In recent versions of .NET, "full trust means full trust". That is, fully-trusted code satisfies all demands, including demands for things like "was signed with this key", whether it actually was signed or not.
Isn't that a deadly flaw in the security system? No. Fully trusted code always had the ability to do that, because fully trusted code has the ability to control the evidence associated with a given assembly. If you can control the evidence,then you can forge an assembly that looks like it came from Microsoft, no problem. (And if you already have malicious full-trust code in your process then you have already lost -- it doesn't need to impersonate Microsoft-signed assemblies; it already has the power to do whatever the user can do.)
Apparently, the .Net designers felt that this attribute wasn't very effective for full trust code in .Net 1.x either.
As Joel indicated, you are out of luck with regard to CAS. However, you may be able to do the check yourself in any method you need to protect by using Assembly.GetCallingAssembly() to get a reference to the assembly containing the calling code, then check the strong name on that assembly manually.