Today, on the series “Exploring the CodeFluent Runtime” we’re going to explore how to sign an application with Authenticode method.
Microsoft Authenticode, which is based on industry standards, allows developers to include information about themselves and their code with their programs through the use of digital signatures. Authenticode allows software vendors to sign:
- .cab files
- .cat files
- .ctl files
- .dll files
- .exe files
- .ocx files
First we need a certificate that allows Code Signing. If you haven’t one, let’s create a self-signed one:
REM May change depending of your installed Windows SDK cd "C:\Program Files (x86)\Microsoft SDKs\Windows\v7.1A\Bin" REM Generate the root certificate .\makecert.exe -r -pe -n "CN=Sample.CA" -ss CA -sr CurrentUser -a sha1 -cy authority -sky signature -sv d:\Sample.CA.pvk d:\Sample.CA.cer REM Add the Root certificate to the user store certutil.exe -user -addstore Root d:\Sample.CA.cer REM Create the certificate for code signing .\makecert.exe -pe -n "CN=Sample.CodeSigning" -eku "126.96.36.199.188.8.131.52.3,184.108.40.206.4.1.3220.127.116.11" -a sha1 -cy end -sky signature -ic d:\Sample.CA.cer -iv d:\Sample.CA.pvk -sv d:\Sample.CodeSigning.pvk d:\Sample.CodeSigning.cer REM Convert to certificate to pfx file format .\pvk2pfx.exe -pvk d:\Sample.CodeSigning.pvk -spc d:\Sample.CodeSigning.cer -pfx d:\Sample.CodeSigning.pfx
For convenience you can add the certificate to the personal store (“My”) by double clicking on it in the explorer.
We can now sign a file. Add the “CodeFluent.Runtime.dll” reference and use the following code:
// If you have zero more than one code signing certificate in the personal store, you have to load the certificate manually. X509Certificate2 certificate = Authenticode.FindSuitableCertificate(); Authenticode.SignFile(certificate, "sample.exe", null, "SoftFluent");
The first line find a valid certificate for code signing in the user certificate store. If none is found, it returns null.
The second line signs the file. You have to indicate:
- the certificate to use
- the file to sign
- the timestamp server
- the display name
If you look at the file properties, you’ll find a new tab ‘Digital Signature’ which contains details about the signer.
- you don’t need to provide a password, nor a path to the certificate => Generic, simple and secure
- the method doesn’t rely on the Windows SDK, so you don’t have to bother with SDK path => much simplier 🙂
- it’s a DLL so it’s very easy to integrate in your application
Additionally you’ll find two methods:
//Determines whether the specified certificate can sign code. public static bool CanSignCode(X509Certificate2 certificate) //Determines whether the specified file is signed using authenticode. public static bool IsSigned(string filePath)
Starting with build 786:
When you sign a file with a timestamp server, an exception is sometimes raised. The workaround is to sign the file without using a timestamp server and then timestamp the signed file:
X509Certificate2 certificate = Authenticode.FindSuitableCertificate(); Authenticode.SignFile(certificate, "sample.exe", null, "Sample"); Authenticode.TimeStampFile("sample.exe", "http://timestamp.verisign.com/scripts/timstamp.dll");
We also introduce a new overload which allow to specify the hash algorithm to use:
Authenticode.SignFile(certificate, "sample.exe", null, "Sample", Authenticode.Sha512AlgorithmId);
The R&D team
CodeFluent Entities can generate out of the box Membership, Role & Profiles Providers. Recently Microsoft release a new Identity system: ASP.NET Identity. As it seems to be more and more use, we decided to write a new producer to support this new Identity system.
First of all, the source code of the producer is available on our GitHub repository.
The producer does two things:
- It assists you in creating ASP.NET Identity entities (User, Role, Claim, Login)
- It generates the UserStore and RoleStore and implements IUser and IRole
How to install
- Download the code from GitHub and compile it. A compiled version is also available here
- Copy the output “CodeFluent.Producers.AspNetIdentity.dll” to “C:\Program Files (x86)\SoftFluent\CodeFluent\Modeler”
- (Optional) To integrate the producer to the graphical modeler copy or merge “custom.config” to “%APPDATA%\CodeFluent.Modeler.Design\custom.config”
How to use it
- Create a CodeFluent Entities project
- Add a Business Object Model (BOM) producer
- Add this new producer (Security -> Asp.Net Identity). Note: The target path has no effect. The target path will be “Target Path of the BOM Producer\Web\Security(User|Role)Store”
- Right click on the producer and click the “Create Identity Entities” menu item
- Select necessary entities (User, Role, Claim, Login) and the destination namespace
- Customize entities. For example you can remove “Password” property if you don’t need it
- Generate and use the code 🙂
Note: you must add the “Microsoft.AspNet.Identity.Core” Nuget package before compiling the generated code (but this is obvious).
CodeFluent Entities is very extensible. As we try to show in this article, one way of extending it is by using producers. Of course the main goal of producers is to generate code. But they can also interact with the model at design time thanks to the CodeFluent Entities API.
Please share your feedbacks about this producer and don’t hesitate to make some suggestion.
The R&D Team.
Two month ago, we heard about a benchmark that fetch performance of .NET Data Access Tools and ORMs. This benchmark has been introduced by Frans Bouma in this following blog post.
We started by creating a simple implementation with CodeFluent Entities and then analyze the result. Thanks to the flexibility of our product, it seems natural for us to provide an optimized but generic implementation. This means that the code is still generated.
CodeFluent Entities provides dynamics modeling features like “Aspects” to implement application-wide behaviors. This is what we call dynamic modeling. In a nutshell, in CodeFluent Entities, dynamic modeling is materialized as aspects and it allows developers to inject extra-behaviors in models.
That’s what gave us the idea of developing a new Aspect called “FasterReader” to reduce the number of data type conversion.
We explained our approach in a blog Post named “Fetch performance of CodeFluent Entities compared to others“.
This Aspect is generic (not “benchmark dedicated”) and can be used in any kind of model.
The initial commit is available here and includes the CodeFluent Entities Model with the SoftFluent.FasterReader.xml aspect.
We also modified the README.MD file with the following changes:
CodeFluent Entities is a Model-First code generator. CodeFluent Entities will access database using automatically generated stored procedures. For more information about CodeFluent Entities and this benchmark: https://blog.codefluententities.com/2014/03/27/fetch-performance-of-codefluent-entities/.
Of course, this readme includes a link to our blog post that explains the approach.
Then, Frans Bouma asked us to make some understandable changes before merging the code:
- remove links to CodeFluent Entities website
- remove a large file with all the procs
- remove useless files in various folders regarding TFS, scc, resx, .user, etc.
- remove the CodeFluent Entities Model
For your information about the last statement: we have chosen to add this project to let users generate again the code and to be completely transparent.
Of course, feedbacks has been considered a few days later:
But… the 5th of May, Frans Bouma removed our code:
With the following reason:
The CodeFluent code was removed as it kept the connection open during
individual fetches which therefore turned out to be faster than everyone
else. This was hard to find, and therefore a form of cheating.
By default, CodeFluent Entities opens one connection per thread but we attempted to explain that we can change this behavior. His reaction was the following:
You will find below the result with the custom configuration:
ADO.NET’s Connection Pooling keeps all connections open so that doesn’t change a lot of things so we don’t change this setting:
We understand the way out products connects to a database out-of-the-box is not ok for Mr Bouma, but we don’t really understand why he went so mad about this, treating us cheaters. Again, this is how it works out-the-box. Why should we investigate why our product – based on stored procedures – is faster than others? Mr Bouma could have discussed with us – like he did in the beginning of the whole process – and we could have changed this default behavior happily to comply with his rules. We were not trying to make a fool of him or to hide crucial information from him, just compete with other products. It’s a sad way of doing thing, and in the end, this behavior does not change anything to the numbers.
Moreover, if you want to check or test our implementation (the Model is included), please visit the following GitHub repository.
The R&D Team.