Automate/script dashboard signing?

Apologies if this has been covered in the past (and feel free to just post a link if so…)

I just read the latest installment in NTDEV of the horror show that is Win10 driver signing. I’ve been busy beating the deadline to use my now-expired SHA-1 cert that allegedly gets a free pass for being a legacy signature, so I’m only now diving into the brave new dystopia of the mechanics of signing drivers for Win10.

The NTDEV article shows how you manually go to the dashboard to get an Attestation Signature, which seemed clear enough. But I’m wondering if there is any way to script this? (or if not, if MS is making noise about adding support for that). The product I support has three separate variants, each with a matrix of four driver builds: x86/x64 on one axis, pre/post Vista on the other. Right now I have build scripts that just run signtool to sign/timestamp all the drivers at the end, which works just dandy.

If I suddenly have to visit a web page by hand to prep these builds, I’m going to pull my hair out. Someone please tell me that there is an automated way to submit your CAB to the portal. (pretty please?)

David Yon
Tactical Software, LLC

On the MSDN pages, there is a REST API mentioned, but haven’t seen this be updated recently:

https://msdn.microsoft.com/en-us/library/windows/hardware/dn800654(v=vs.85).aspx

xxxxx@rfdsoftware.com wrote:

Apologies if this has been covered in the past (and feel free to just post a link if so…)

These days, it is never necessary to apologize for asking a signing
question. Even if the question has been asked before, the answer has
probably changed, or at least been re-interpreted.

The NTDEV article shows how you manually go to the dashboard to get an Attestation Signature, which seemed clear enough. But I’m wondering if there is any way to script this? (or if not, if MS is making noise about adding support for that). The product I support has three separate variants, each with a matrix of four driver builds: x86/x64 on one axis, pre/post Vista on the other. Right now I have build scripts that just run signtool to sign/timestamp all the drivers at the end, which works just dandy.

According to the OSR/Microsoft interview last July, there is currently a
web API for managing WHQL submissions, but the attestation signing
pipeline is not part of that API yet. At that time, he did not have a
schedule for when that might happen.

And, frustratingly, the MSDN link that Peter conveniently included in
his transcription of the interview now points to the very helpful
“Content Removed” page. I find it utterly unbelievable that a
technology-centric company like Microsoft cannot figure out how to make
all MSDN links live forever. It’s just not that hard. Namespace does
not cost any extra.

So, for now, it’s manual.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

xxxxx@videotron.ca wrote:

On the MSDN pages, there is a REST API mentioned, but haven’t seen this be updated recently:

https://msdn.microsoft.com/en-us/library/windows/hardware/dn800654(v=vs.85).aspx

Yes, but I don’t think the attestation signing is part of that yet. I
believe that’s just for WHQL submissions.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Thanks everyone so far. If I get to the point where my somewhat odd-duck software-only legacy driver can survive certification testing, then a REST API for automating that will suffice. If I have to settle for Attestation, then like everyone else here, I’m at the mercy of MS to add support for that.

This whole thing is the biggest WTF I’ve seen in a long time, from MS or anybody else for that matter.

I’m trying to use this REST API to automate driver signing during build process in different projects. We decided to create our internal server that will communicate with Microsoft sysdev server because we have only one token (and EV certificate).
For now we have a nodeJS backend under IIS to handle requests from our developer’s teams. nodeJS communicates with sysdev.

First of all, we use https://msdn.microsoft.com/en-us/library/windows/hardware/dn800660.aspx as a guide.

There are some problems that we haven’t fixed yet.

  1. There are some limits to access to certificate on the token. You can set an option to sign in only once per session, but you still have to enter the password once in SafeNet Authentication Client GUI. Thread context under IIS has something that prevent access to the token, even psexec didn’t help. signtool can’t find the certificate.
  2. In the mentioning link I found an error in the example (pt. 4). It should be “Content-MD5” instead of “MD5-Content” (https://msdn.microsoft.com/en-us//library/azure/dd179451.aspx). So I can’t upload a file (I get checksum failed error).
  3. I didn’t find the way to cancel the submission by the REST API. I do it manually through the web portal after my tests and it painful.
  4. There is no way to delete a submission. My list of submissions after my experiments has a lot of pages now…

It will be more more helpful if Microsoft shows usable full source code.

If someone has done it in any way I will be glad to hear your advice.

xxxxx@mail.ru wrote:

There are some problems that we haven’t fixed yet.

If someone has done it in any way I will be glad to hear your advice.

So, you have successfully been able to submit an attestation package
through your code? Is this something you could share with the community?


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

You understand that your submission does NOT need a o be signed with your EV cert, right?

It has to be signed by a cert registered to your sys dev account, and your sys dev account has tone associated with an EV cert… But the aubmission itself does not need to be signed by the EV cert.

Peter
OSR
@OSRDrivers

Peter,

I believe this will only work until some time this year.
From https://msdn.microsoft.com/library/windows/hardware/89cf1c2c-9342-4bf4-a8ee-fe33d7c024e5?f=255&MSPPError=-2147217396#Code_Signing_FAQ :
“You can sign with either your EV certificate or your existing standard certificates until May 1, 2016. After May 1, 2016, you need to use an EV certificate to sign the cab file that is submitted.”

Roney

On 6/22/16, 9:56 AM, “xxxxx@lists.osr.com on behalf of xxxxx@osr.com” wrote:

You understand that your submission does NOT need a o be signed with your EV cert, right?

It has to be signed by a cert registered to your sys dev account, and your sys dev account has tone associated with an EV cert… But the aubmission itself does not need to be signed by the EV cert.

Peter
OSR
@OSRDrivers


NTDEV is sponsored by OSR

Visit the list online at: http:

MONTHLY seminars on crash dump analysis, WDF, Windows internals and software drivers!
Details at http:

To unsubscribe, visit the List Server section of OSR Online at http:</http:></http:></http:>

Hi, Tim Roberts!

Currently I stuck in p.5 of https://msdn.microsoft.com/en-us/library/windows/hardware/dn800660.aspx. After I send UpdateComplete I always get 404. On dashboard I see a new submission without package.

Can someone from MS review it?

source:

static void UploadFile(string sasUrl, string filepath, string SessionGuid)
{
Console.WriteLine(“Uploadfile:\n {0}\n {1}\n {2}\n”, filepath, sasUrl, SessionGuid);

using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Add(“x-ms-version”, “2013-08-15”);
client.DefaultRequestHeaders.Add(“x-ms-client-request-id”, SessionGuid);

StringBuilder sb = new StringBuilder(“<?xml version=\"1.0\" encoding=\"utf-8\"?>”);

int bytesRead = 0;
int Offset = 0;
// Read the source file into a byte array.
byte bytes = new byte[1024 * 1024];
FileStream SourceStream = new FileStream(filepath, FileMode.Open, FileAccess.Read);
bytesRead = GetFileChunks(SourceStream, Offset, ref bytes);

while (bytesRead > 0)
{
string blockid = GetHash(bytes);

HttpRequestMessage chunkMessage = new HttpRequestMessage()
{
Method = HttpMethod.Put,
RequestUri = new Uri(sasUrl + “&timeout=90&comp=block&blockid=” + WebUtility.UrlEncode(blockid)),
Content = new ByteArrayContent(bytes)
};

chunkMessage.Headers.Add(“x-ms-blob-type”, “BlockBlob”);
chunkMessage.Content.Headers.Add(“Content-MD5”, blockid);

Console.WriteLine(“Uploading chunk {0}\n”, blockid);

// TimeAction(“Uploading chunk " + blockid + " took {0} ms”, () =>
{
var response = client.SendAsync(chunkMessage).Result;
Console.WriteLine(“{0} ({1})”, (int)response.StatusCode, response.ReasonPhrase);
}
// );
sb.Append(“”);
sb.Append(blockid);
sb.Append(“”);

Offset = Offset + bytesRead;
bytesRead = GetFileChunks(SourceStream, Offset, ref bytes);
}

sb.Append(“”);

Console.WriteLine(“{0}\n”, sb.ToString());

HttpRequestMessage commitMessage = new HttpRequestMessage()
{
Method = HttpMethod.Put,
RequestUri = new Uri(sasUrl + “&timeout=90&comp=blocklist”),
Content = new StringContent(sb.ToString())
};

Console.WriteLine(“Committing the blocks…\n”);

// TimeAction(“Commiting the blocks took {0} ms”, () =>
{
var commit = client.SendAsync(commitMessage).Result;
Console.WriteLine(“{0} ({1})”, (int)commit.StatusCode, commit.ReasonPhrase);
}
// );
}
}

private static string GetHash(byte bytes)
{
string hash;
using (MD5 md5Hash = MD5.Create())
{
hash = Convert.ToBase64String(md5Hash.ComputeHash(bytes));
}

return hash;
}

private static int GetFileChunks(FileStream SourceStream, int offset, ref byte buf)
{
try
{
// Read the source file into a byte array.

int numBytesToRead = (int)1024 * 1024;
// Read may return anything from 0 to numBytesToRead.
return SourceStream.Read(buf, offset, numBytesToRead);
}
catch (SystemException ioEx)
{
Console.WriteLine(ioEx.Message);
}

return 0;
}

As of my discussion with the relevant Microsoft PM last week, this policy has been changed. This was also discussed in detail at IFS PlugFest last month. You can see watch the talk on signing here:

https:

Peter
OSR
@OSRDrivers</https:>

> bytesRead = GetFileChunks(SourceStream, Offset, ref bytes);

Why do you need “ref” here?

“bytes” is a System.Array, which is the by-reference object anyway - like any other .NET object.

You can just pass “bytes”. This will pass the .NET moref to the System.Array object, and GetFileChunks will be able to fill the values contained in it.


Maxim S. Shatskih
Microsoft MVP on File System And Storage
xxxxx@storagecraft.com
http://www.storagecraft.com

> > bytesRead = GetFileChunks(SourceStream, Offset, ref bytes)

Why do you need “ref” here?

“bytes” is a System.Array, which is the by-reference object anyway - like any
other .NET object.

You may need “ref” because the function can reallocate the array. For example, within the function you could have:

bytes= new bytes[1000];

Without the ‘ref’ you’d only be changing a local copy of the parameter, with the ref you are changing the value seen by the caller.

Btw: if the callee always allocates the array, and the caller never does, then the “out” keyword is ‘more correct’ than “ref”.

* Bob

? Bob AmmerI knman
? xxxxx@ramsystems.biz
716.864.8337

138 Liston St
Buffalo, NY 14223
www.ramsystems.biz