Secure RESTful WCF Service with SHA-256 hashing

This is an old draft I found, perhaps it is useful if you’re trying to do SHA-256. If not, let me know, I might be able to help you out. Azure Storage supports secure access of resources without logon. It involves hashing the query part of the URL and then signing that hash. I’ve implemented this at my workplace in the following steps:

  • Create a web project for a WCF service.
  • Update the .svc file by adding (this makes everything work without configuration, found this here):

Factory="System.ServiceModel.Activation.WebServiceHostFactory"

  • Add the following attribute to your interface method:

[WebInvoke(Method = "GET", BodyStyle = WebMessageBodyStyle.Bare, UriTemplate = "?p0={parameter0}&p1={parameter1}&sig={signature}")]

  • Create a method like (please note that parameter names match those specified in the WebInvoke attribute and that they are all string type):

Stream MyMethod(string parameter0, string parameter1, string signature);

  • In the implementation of MyMethod verify the signature with the following function:

bool ValidSignature(string customerID, string signature, params string[] toSignArguments)
{
var certificate = FindCertificate(customerID);
if (certificate == null) {
return false;
}
const string TERMINATOR = "\n";
var toSign = string.Join(TERMINATOR, toSignArguments) + TERMINATOR;
var oldProvider = (RSACryptoServiceProvider)certificate.PublicKey.Key;
using (var newProvider = new RSACryptoServiceProvider())
{
newProvider.ImportCspBlob(oldProvider.ExportCspBlob(false));
return newProvider.VerifyData(Encoding.UTF8.GetBytes(toSign), "SHA256", Convert.FromBase64String(signature));
}
}

The trick is to create a new provider instead of the default one you get when loading the key. The default is connected to the wrong library that doesn’t support SHA-256.

Advertisements

How to send SQL from Visual Studio into a User Instance

I really like SQL Express user instances for prototype projects but to send plain SQL commands into them is tricky. I finally found a way:

In Visual Studio create a new SQL file or open an existing one.

With the SQL file open the connect dialog.

Connect to database from Visual Studio

The Connect Dialog will pop up.

Visual Studio 2010 Connect Dialog

Click Options.

Click the “Additional Connection Parameters” tab and type “User Instance=true”.

The connect options User Instance

Click Connect.

Select the appropriate user instance (database name looks like a file path).

Select the User Instance to connect to.

That’s it! Now you can fire plain SQL at your user instance.

Guerrilla Build Scripting in F# Interactive

If you’re one of the “lucky few” having to use Visual Studio 2010 in combination with Visual SourceSafe 2005 (please don’t ask why) you might find this script useful. I use it to give each release build a new version number. To do this I’ve created a separate C# file with an AssemblyFileVersion attribute that’s added as a link in each C# project. My script checks out the file, increments the build number and checks it back in.

// Increase build number in AssemblyFileVersion.cs and store it in SourceSafe.
open System
open System.Diagnostics
open System.IO
open System.Text.RegularExpressions

let versionFileName = @"AssemblyFileVersion.cs"

// Run SourceSafe command-line on specified db (folder) with specified arguments
// (see http://msdn.microsoft.com/en-us/library/bh58tzy9(v=vs.80).aspx).
let runSS db arg =
    let ssPath =
        // For custom install path use
        // HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\SourceSafe\SCCServerPath.
        if Environment.Is64BitOperatingSystem then
            @"C:\Program Files (x86)\Microsoft Visual SourceSafe\ss.exe"
        else
            @"C:\Program Files\Microsoft Visual SourceSafe\ss.exe"
    let info = new ProcessStartInfo(ssPath, arg)
    info.EnvironmentVariables.Add("SSDIR", db)
    info.UseShellExecute <- false
    info.RedirectStandardError <- true
    let ss = Process.Start(info)
    ss.WaitForExit()
    if ss.ExitCode <> 0 then
        let errors = ss.StandardError.ReadToEnd()
        printfn "Errors running ss: %s" errors
    ss.WaitForExit()

// Get VSS database and path of this solution.
let scc =
    use file = new StreamReader(@"mssccprj.scc")
    file.ReadToEnd()
let dbEx = Regex("SCC_Aux_Path = \"(?'DB'[^\"]+)\"")
let db = dbEx.Match(scc).Groups.["DB"].Value
let pathEx = Regex("SCC_Project_Name = \"(?'Path'[^\"]+)\"")
let path = pathEx.Match(scc).Groups.["Path"].Value + "/" + versionFileName

printfn "Checkout '%s' in db '%s'." path db
runSS db ("Checkout \"" + path + "\"")

// Get buildnumber in file, increment it and write it back.
let contents =
    use file = new StreamReader(versionFileName)
    file.ReadToEnd()
let buildEx = Regex("(\[assembly: AssemblyFileVersion\(\"(\d+\.){3})?(?'BuildNumber'\d+)(\"\)\])?")
let oldBuildNumber = Int32.Parse(buildEx.Match(contents).Groups.["BuildNumber"].Value)
let newBuildNumber = oldBuildNumber + 1
let newVersion = buildEx.Replace(contents, "${1}" + newBuildNumber.ToString() + "$3")
printfn "New build number %d." newBuildNumber
let writeVersion () =
    use file = new StreamWriter(versionFileName)
    file.Write(newVersion)
writeVersion ()

printfn "Checkin '%s'" path
runSS db ("Checkin \"" + path + "\" -C-")