New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Appx/AppxBundle support #2

Closed
onovotny opened this Issue Sep 5, 2017 · 27 comments

Comments

2 participants
@onovotny
Collaborator

onovotny commented Sep 5, 2017

Might be worth spelling out what's required for appx/appxbundles. I think files from the Windows SDK directory need to be in the same directory (possibly the wintrust.dll/wintrust.dll.ini) as this tool along with some of the Opc dll's. I know it needs some of the exe's in there too.

I can play with this later this week.

@onovotny onovotny self-assigned this Sep 5, 2017

@vcsjones

This comment has been minimized.

Show comment
Hide comment
@vcsjones

vcsjones Sep 5, 2017

Owner

I think APPX will take some extra effort. It looks like signtool is specifying "extra" data in the SIP data. Currently I am passing in null since most things don't actually use it. I'll work on that.

Owner

vcsjones commented Sep 5, 2017

I think APPX will take some extra effort. It looks like signtool is specifying "extra" data in the SIP data. Currently I am passing in null since most things don't actually use it. I'll work on that.

@onovotny

This comment has been minimized.

Show comment
Hide comment
@onovotny

onovotny Sep 5, 2017

Collaborator

@vcsjones Something isn't working here...even with the local files and manifest. Getting an error if I use AzureSignTool but the SignToolWrapper works. Changes are in https://github.com/onovotny/SignService/tree/azuresigntool

You do need to use the signservice instead of invoking the AzureSignTool directly since it modifies the appx manifest files as required since the CN has to match.

Collaborator

onovotny commented Sep 5, 2017

@vcsjones Something isn't working here...even with the local files and manifest. Getting an error if I use AzureSignTool but the SignToolWrapper works. Changes are in https://github.com/onovotny/SignService/tree/azuresigntool

You do need to use the signservice instead of invoking the AzureSignTool directly since it modifies the appx manifest files as required since the CN has to match.

@vcsjones

This comment has been minimized.

Show comment
Hide comment
@vcsjones

vcsjones Sep 5, 2017

Owner

@onovotny
Yep. See my original reply. A parameter isn't being filled in that is required for APPX.

Owner

vcsjones commented Sep 5, 2017

@onovotny
Yep. See my original reply. A parameter isn't being filled in that is required for APPX.

@onovotny

This comment has been minimized.

Show comment
Hide comment
@onovotny

onovotny Sep 5, 2017

Collaborator

To debug with the SignClient, you can update the appsettings to include your url/client id and resource id of the service

Then use a launch setting of something like

    "SignClient-Appx": {
      "commandName": "Project",
      "commandLineArgs": "sign -c c:\\dev\\SignService\\src\\SignClient\\appsettings.json -i C:\\dev\\signtest\\App3.appx -o C:\\dev\\signtest\\signed\\App3.appx -s <clientSecret> -n Oren"
    },

Alternatively, if you send me the public cert of cert you're using, I can make the manifest changes and give you a "blank" appx that's ready for signing so you don't need the sign service.

Collaborator

onovotny commented Sep 5, 2017

To debug with the SignClient, you can update the appsettings to include your url/client id and resource id of the service

Then use a launch setting of something like

    "SignClient-Appx": {
      "commandName": "Project",
      "commandLineArgs": "sign -c c:\\dev\\SignService\\src\\SignClient\\appsettings.json -i C:\\dev\\signtest\\App3.appx -o C:\\dev\\signtest\\signed\\App3.appx -s <clientSecret> -n Oren"
    },

Alternatively, if you send me the public cert of cert you're using, I can make the manifest changes and give you a "blank" appx that's ready for signing so you don't need the sign service.

@vcsjones

This comment has been minimized.

Show comment
Hide comment
@vcsjones

vcsjones Sep 5, 2017

Owner

The gist of it is, the pSipData parameter needs to get a pointer to a APPX_SIP_CLIENT_DATA structure.

Owner

vcsjones commented Sep 5, 2017

The gist of it is, the pSipData parameter needs to get a pointer to a APPX_SIP_CLIENT_DATA structure.

@onovotny

This comment has been minimized.

Show comment
Hide comment
@onovotny

onovotny Sep 5, 2017

Collaborator

@vcsjones missed your original reply! :)

either way, I can give you a ready appx that's filled in with the required info that should work if you don't want to get the sign service working locally.

Collaborator

onovotny commented Sep 5, 2017

@vcsjones missed your original reply! :)

either way, I can give you a ready appx that's filled in with the required info that should work if you don't want to get the sign service working locally.

@onovotny

This comment has been minimized.

Show comment
Hide comment
Collaborator

onovotny commented Sep 5, 2017

@vcsjones

This comment has been minimized.

Show comment
Hide comment
@vcsjones

vcsjones Sep 5, 2017

Owner

Yeah I have a good idea what needs to be done. A test file would be super helpful. Can drop to my inbox. Cert:

-----BEGIN CERTIFICATE-----
MIIFHjCCBAagAwIBAgIQB6D3F+HHUDhB9AL42AtX1zANBgkqhkiG9w0BAQsFADBy
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMTEwLwYDVQQDEyhEaWdpQ2VydCBTSEEyIEFzc3VyZWQg
SUQgQ29kZSBTaWduaW5nIENBMB4XDTE3MDgzMTAwMDAwMFoXDTE4MDkwNTEyMDAw
MFowWzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlZBMRMwEQYDVQQHEwpBbGV4YW5k
cmlhMRQwEgYDVQQKEwtLZXZpbiBKb25lczEUMBIGA1UEAxMLS2V2aW4gSm9uZXMw
ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCaoDIPfbv+5PL1+3JPD2mI
VHhLBM5izxA4voVg3Fju9PxpvPwURMgmGiKdyLm/Jx8QSL6F+azDoj3VlId2uLZT
WVVXC8O+1XWZJWOF9Mhc2UJfhIbkL0Ah5VwWK3ZAzrE0EdLqXnE5ae7aPOL0N2Re
n8sEslXMHgHkwlTQsu6omj2CrCVvH2pp1VVuhBeUx7DAfHOJSLvTYGcjTxJkRf9m
l48bD57JsY+rQE+kpZleimQyKV0mc284PAH7Od2pThQ9+zZ9chSoV0x8DkPD1KR3
5CKlXwBjAvHnzWc6SRLaz+svmHN8rxBHGvamSwYSFO/Zc+dHdjw2x2rherZl3jq9
AgMBAAGjggHFMIIBwTAfBgNVHSMEGDAWgBRaxLl7KgqjpepxA8Bg+S32ZXUOWDAd
BgNVHQ4EFgQUeVZZJ1OYKpUiUtOAdVrns0q/y14wDgYDVR0PAQH/BAQDAgeAMBMG
A1UdJQQMMAoGCCsGAQUFBwMDMHcGA1UdHwRwMG4wNaAzoDGGL2h0dHA6Ly9jcmwz
LmRpZ2ljZXJ0LmNvbS9zaGEyLWFzc3VyZWQtY3MtZzEuY3JsMDWgM6Axhi9odHRw
Oi8vY3JsNC5kaWdpY2VydC5jb20vc2hhMi1hc3N1cmVkLWNzLWcxLmNybDBMBgNV
HSAERTBDMDcGCWCGSAGG/WwDATAqMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5k
aWdpY2VydC5jb20vQ1BTMAgGBmeBDAEEATCBhAYIKwYBBQUHAQEEeDB2MCQGCCsG
AQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wTgYIKwYBBQUHMAKGQmh0
dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFNIQTJBc3N1cmVkSURD
b2RlU2lnbmluZ0NBLmNydDAMBgNVHRMBAf8EAjAAMA0GCSqGSIb3DQEBCwUAA4IB
AQAcdhriO23gHGuwu96n4Cg76AwBMiNExxbZU/8XkQuII+ng6dJnmhmVRCuMkrsY
bnVOtNkg1xd23WYT+2UqkcKRaUhYLh8ATtkdNTlQ4WoxZb66FZfvm+nagNlOtn5h
8vM1GzJazVlOJhXIuEPc/K/ZpIMrW6pM/nK4n5vMV6dzZFWv95+lTyVDsEcgwlEM
0thdDYF+ztMDYAP3ZjP1a5F38s5xprwstrtljcsJhSy62MrFOve0/FuVto7ThxI9
3slq3HA6UBRS21dbQd3npHRls9Dgpq8k9ga+91Hl2jYAX5M1QSQjKNPY4MFgv/yf
lYR6/8MdNq25KD6DIRMYifSE
-----END CERTIFICATE-----
Owner

vcsjones commented Sep 5, 2017

Yeah I have a good idea what needs to be done. A test file would be super helpful. Can drop to my inbox. Cert:

-----BEGIN CERTIFICATE-----
MIIFHjCCBAagAwIBAgIQB6D3F+HHUDhB9AL42AtX1zANBgkqhkiG9w0BAQsFADBy
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMTEwLwYDVQQDEyhEaWdpQ2VydCBTSEEyIEFzc3VyZWQg
SUQgQ29kZSBTaWduaW5nIENBMB4XDTE3MDgzMTAwMDAwMFoXDTE4MDkwNTEyMDAw
MFowWzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlZBMRMwEQYDVQQHEwpBbGV4YW5k
cmlhMRQwEgYDVQQKEwtLZXZpbiBKb25lczEUMBIGA1UEAxMLS2V2aW4gSm9uZXMw
ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCaoDIPfbv+5PL1+3JPD2mI
VHhLBM5izxA4voVg3Fju9PxpvPwURMgmGiKdyLm/Jx8QSL6F+azDoj3VlId2uLZT
WVVXC8O+1XWZJWOF9Mhc2UJfhIbkL0Ah5VwWK3ZAzrE0EdLqXnE5ae7aPOL0N2Re
n8sEslXMHgHkwlTQsu6omj2CrCVvH2pp1VVuhBeUx7DAfHOJSLvTYGcjTxJkRf9m
l48bD57JsY+rQE+kpZleimQyKV0mc284PAH7Od2pThQ9+zZ9chSoV0x8DkPD1KR3
5CKlXwBjAvHnzWc6SRLaz+svmHN8rxBHGvamSwYSFO/Zc+dHdjw2x2rherZl3jq9
AgMBAAGjggHFMIIBwTAfBgNVHSMEGDAWgBRaxLl7KgqjpepxA8Bg+S32ZXUOWDAd
BgNVHQ4EFgQUeVZZJ1OYKpUiUtOAdVrns0q/y14wDgYDVR0PAQH/BAQDAgeAMBMG
A1UdJQQMMAoGCCsGAQUFBwMDMHcGA1UdHwRwMG4wNaAzoDGGL2h0dHA6Ly9jcmwz
LmRpZ2ljZXJ0LmNvbS9zaGEyLWFzc3VyZWQtY3MtZzEuY3JsMDWgM6Axhi9odHRw
Oi8vY3JsNC5kaWdpY2VydC5jb20vc2hhMi1hc3N1cmVkLWNzLWcxLmNybDBMBgNV
HSAERTBDMDcGCWCGSAGG/WwDATAqMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5k
aWdpY2VydC5jb20vQ1BTMAgGBmeBDAEEATCBhAYIKwYBBQUHAQEEeDB2MCQGCCsG
AQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wTgYIKwYBBQUHMAKGQmh0
dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFNIQTJBc3N1cmVkSURD
b2RlU2lnbmluZ0NBLmNydDAMBgNVHRMBAf8EAjAAMA0GCSqGSIb3DQEBCwUAA4IB
AQAcdhriO23gHGuwu96n4Cg76AwBMiNExxbZU/8XkQuII+ng6dJnmhmVRCuMkrsY
bnVOtNkg1xd23WYT+2UqkcKRaUhYLh8ATtkdNTlQ4WoxZb66FZfvm+nagNlOtn5h
8vM1GzJazVlOJhXIuEPc/K/ZpIMrW6pM/nK4n5vMV6dzZFWv95+lTyVDsEcgwlEM
0thdDYF+ztMDYAP3ZjP1a5F38s5xprwstrtljcsJhSy62MrFOve0/FuVto7ThxI9
3slq3HA6UBRS21dbQd3npHRls9Dgpq8k9ga+91Hl2jYAX5M1QSQjKNPY4MFgv/yf
lYR6/8MdNq25KD6DIRMYifSE
-----END CERTIFICATE-----
@onovotny

This comment has been minimized.

Show comment
Hide comment
@onovotny

onovotny Sep 5, 2017

Collaborator

Will get you a file as soon as I can. that msdn article appears to cover it. Looks like that AppX SIP state is really a pointer to the signing params, probably so it can access things like the cert/subject or whatever. There's also something that needs to be released if not null.

Collaborator

onovotny commented Sep 5, 2017

Will get you a file as soon as I can. that msdn article appears to cover it. Looks like that AppX SIP state is really a pointer to the signing params, probably so it can access things like the cert/subject or whatever. There's also something that needs to be released if not null.

@vcsjones

This comment has been minimized.

Show comment
Hide comment
@vcsjones

vcsjones Sep 5, 2017

Owner

@onovotny Yeah. I'm curious if the struct is different for SignerSignEx3. I'll be able to tell with WinDbg as soon as I get a file to play with.

Owner

vcsjones commented Sep 5, 2017

@onovotny Yeah. I'm curious if the struct is different for SignerSignEx3. I'll be able to tell with WinDbg as soon as I get a file to play with.

@onovotny

This comment has been minimized.

Show comment
Hide comment
@onovotny

onovotny Sep 5, 2017

Collaborator

I wouldn't think they changed that particular struct since it seems to do all that it needs. anything is possible though.

Collaborator

onovotny commented Sep 5, 2017

I wouldn't think they changed that particular struct since it seems to do all that it needs. anything is possible though.

@onovotny

This comment has been minimized.

Show comment
Hide comment
@onovotny

onovotny Sep 5, 2017

Collaborator

this file should work with your cert.

App4.appx.zip

Basically the publisher attribute has to match the subject of the cert.

Collaborator

onovotny commented Sep 5, 2017

this file should work with your cert.

App4.appx.zip

Basically the publisher attribute has to match the subject of the cert.

@vcsjones

This comment has been minimized.

Show comment
Hide comment
@vcsjones

vcsjones Sep 5, 2017

Owner

@onovotny Thanks. I can sign that with signtool, so I have a working case.

What native libs are you copying over from the SDK?

Owner

vcsjones commented Sep 5, 2017

@onovotny Thanks. I can sign that with signtool, so I have a working case.

What native libs are you copying over from the SDK?

@vcsjones

This comment has been minimized.

Show comment
Hide comment
@vcsjones

vcsjones Sep 6, 2017

Owner

@onovotny So bad news and good news.

Bad news. The struct that goes to the sipData column is almost certainly different from the one in the example MSDN article. The tl;dr: the memory layout is different and does not even come close to doing what is in the MSDN article. Ha.

Good news. I think I figured out the new struct layout. Can you make a new AppX for me with this self-signed cert?

-----BEGIN CERTIFICATE-----
MIIDbjCCAlagAwIBAgIQboJB+8ZmSQWQUv02GYw4kzANBgkqhkiG9w0BAQsFADA5
MQ0wCwYDVQQKEwRURVNUMQ0wCwYDVQQLEwRURVNUMRkwFwYDVQQDExBPcGVuVnNp
eFNpZ25Ub29sMB4XDTE3MDUwMzIxMDYxNloXDTI0MTEwMzIxMTYxNlowOTENMAsG
A1UEChMEVEVTVDENMAsGA1UECxMEVEVTVDEZMBcGA1UEAxMQT3BlblZzaXhTaWdu
VG9vbDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJjCJx3VwTtznKJn
amqQjG3wBlc7qTiKieJZ5ViIHol3mfkixRRoeAYX97mo3o2D0XjuKBSvXGtNADLh
iw2QR9OZ4EFax0geZbB3D3cNb+pLW5BMsBARk+Eflyesye16CY9lCUAfrCjlauBl
WzUZbNfsoGwuLe8sjcU1LipZ+lc9iSj9z3rv8DnooY1H/QpPXAkomQkMCbZ//y46
e2LCZZRq547W6lmOLMb3zj4jeIFyqMg8TGuTG1WYNaenN2B1pkACJZjGuGtx28Te
O/IryIA5KIrDf5VL+oD0u1kS8JX96pjudeNBiIYhimaX4XHX0HSLMsH35WMuB0Fo
gwjGajECAwEAAaNyMHAwDgYDVR0PAQH/BAQDAgWgMAkGA1UdEwQCMAAwEwYDVR0l
BAwwCgYIKwYBBQUHAwMwHwYDVR0jBBgwFoAUiaZ/RM6PQM8N7rJJ2ovT8SxWjJsw
HQYDVR0OBBYEFImmf0TOj0DPDe6ySdqL0/EsVoybMA0GCSqGSIb3DQEBCwUAA4IB
AQBItl2yB9bXQvutRjgKDUKYgdi7UN16yi7rDPQ6rqeK7Ai5fc1sdTMgxbfnyafP
+qstinOUR5Zu73cPqpOIFK0e5hcgq9f0tga3K7xk85VDkMhiaUKwpDDQALgiPN/v
YDvR5rpcFgdyNTC98rZoO9V/tO6MGP9WvNb8a8zrPs91jUfupIADNNzpv0AjP3yS
K4PKP+gEVxOJ0GHiyT6eHe+T3DRdy90l6RyeOb0ENg0EPj+42vyAQ/5fwDy2YHus
2T9itJ092gyUPQQg8YiLctNvFS5qPtOYTNdmeYfY6Ek/ZTXByYaxs3LrwlNYfsNK
9aBvXvRNJzgNCCyLfjMqS/a8
-----END CERTIFICATE-----
Owner

vcsjones commented Sep 6, 2017

@onovotny So bad news and good news.

Bad news. The struct that goes to the sipData column is almost certainly different from the one in the example MSDN article. The tl;dr: the memory layout is different and does not even come close to doing what is in the MSDN article. Ha.

Good news. I think I figured out the new struct layout. Can you make a new AppX for me with this self-signed cert?

-----BEGIN CERTIFICATE-----
MIIDbjCCAlagAwIBAgIQboJB+8ZmSQWQUv02GYw4kzANBgkqhkiG9w0BAQsFADA5
MQ0wCwYDVQQKEwRURVNUMQ0wCwYDVQQLEwRURVNUMRkwFwYDVQQDExBPcGVuVnNp
eFNpZ25Ub29sMB4XDTE3MDUwMzIxMDYxNloXDTI0MTEwMzIxMTYxNlowOTENMAsG
A1UEChMEVEVTVDENMAsGA1UECxMEVEVTVDEZMBcGA1UEAxMQT3BlblZzaXhTaWdu
VG9vbDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJjCJx3VwTtznKJn
amqQjG3wBlc7qTiKieJZ5ViIHol3mfkixRRoeAYX97mo3o2D0XjuKBSvXGtNADLh
iw2QR9OZ4EFax0geZbB3D3cNb+pLW5BMsBARk+Eflyesye16CY9lCUAfrCjlauBl
WzUZbNfsoGwuLe8sjcU1LipZ+lc9iSj9z3rv8DnooY1H/QpPXAkomQkMCbZ//y46
e2LCZZRq547W6lmOLMb3zj4jeIFyqMg8TGuTG1WYNaenN2B1pkACJZjGuGtx28Te
O/IryIA5KIrDf5VL+oD0u1kS8JX96pjudeNBiIYhimaX4XHX0HSLMsH35WMuB0Fo
gwjGajECAwEAAaNyMHAwDgYDVR0PAQH/BAQDAgWgMAkGA1UdEwQCMAAwEwYDVR0l
BAwwCgYIKwYBBQUHAwMwHwYDVR0jBBgwFoAUiaZ/RM6PQM8N7rJJ2ovT8SxWjJsw
HQYDVR0OBBYEFImmf0TOj0DPDe6ySdqL0/EsVoybMA0GCSqGSIb3DQEBCwUAA4IB
AQBItl2yB9bXQvutRjgKDUKYgdi7UN16yi7rDPQ6rqeK7Ai5fc1sdTMgxbfnyafP
+qstinOUR5Zu73cPqpOIFK0e5hcgq9f0tga3K7xk85VDkMhiaUKwpDDQALgiPN/v
YDvR5rpcFgdyNTC98rZoO9V/tO6MGP9WvNb8a8zrPs91jUfupIADNNzpv0AjP3yS
K4PKP+gEVxOJ0GHiyT6eHe+T3DRdy90l6RyeOb0ENg0EPj+42vyAQ/5fwDy2YHus
2T9itJ092gyUPQQg8YiLctNvFS5qPtOYTNdmeYfY6Ek/ZTXByYaxs3LrwlNYfsNK
9aBvXvRNJzgNCCyLfjMqS/a8
-----END CERTIFICATE-----
@onovotny

This comment has been minimized.

Show comment
Hide comment
@onovotny

onovotny Sep 6, 2017

Collaborator

all you need to do is extract the appx (it's a zip file), update the appxmanifest.xml file's Identity element publisher attribute with the subject of your cert.

Here's what I copied from the sdk, though I don't know if it's all necessary https://github.com/onovotny/SignService/blob/master/src/SignService/SignService.csproj#L11-L26

Collaborator

onovotny commented Sep 6, 2017

all you need to do is extract the appx (it's a zip file), update the appxmanifest.xml file's Identity element publisher attribute with the subject of your cert.

Here's what I copied from the sdk, though I don't know if it's all necessary https://github.com/onovotny/SignService/blob/master/src/SignService/SignService.csproj#L11-L26

@vcsjones

This comment has been minimized.

Show comment
Hide comment
@vcsjones

vcsjones Sep 6, 2017

Owner

Awesome, thanks.

Owner

vcsjones commented Sep 6, 2017

Awesome, thanks.

@onovotny

This comment has been minimized.

Show comment
Hide comment
@onovotny

onovotny Sep 6, 2017

Collaborator

if you want, you can use makeappx pack /d <path to extracted files> /p output.appx /o /l to re-pack it, but zipping should work too

the code for this is all here: https://github.com/onovotny/SignService/blob/master/src/SignService/Utils/AppxFile.cs#L104

Collaborator

onovotny commented Sep 6, 2017

if you want, you can use makeappx pack /d <path to extracted files> /p output.appx /o /l to re-pack it, but zipping should work too

the code for this is all here: https://github.com/onovotny/SignService/blob/master/src/SignService/Utils/AppxFile.cs#L104

@onovotny

This comment has been minimized.

Show comment
Hide comment
@onovotny

onovotny Sep 6, 2017

Collaborator

If the existing one is

typedef struct _APPX_SIP_CLIENT_DATA
{
    PSIGNER_SIGN_EX2_PARAMS pSignerParams;
    IUnknown* pAppxSipState;
} 

Wouldn't the new one be

typedef struct _APPX_SIP_CLIENT_DATA
{
    PSIGNER_SIGN_EX3_PARAMS pSignerParams;
    IUnknown* pAppxSipState;
} 

Where PSIGNER_SIGN_EX3_PARAMS matches the SignerSignEx3 args? Or is that too easy? :)

Collaborator

onovotny commented Sep 6, 2017

If the existing one is

typedef struct _APPX_SIP_CLIENT_DATA
{
    PSIGNER_SIGN_EX2_PARAMS pSignerParams;
    IUnknown* pAppxSipState;
} 

Wouldn't the new one be

typedef struct _APPX_SIP_CLIENT_DATA
{
    PSIGNER_SIGN_EX3_PARAMS pSignerParams;
    IUnknown* pAppxSipState;
} 

Where PSIGNER_SIGN_EX3_PARAMS matches the SignerSignEx3 args? Or is that too easy? :)

@vcsjones

This comment has been minimized.

Show comment
Hide comment
@vcsjones

vcsjones Sep 6, 2017

Owner

Where PSIGNER_SIGN_EX3_PARAMS matches the SignerSignEx3 args?

Probably! There is one interesting thing about all of the SignerSignEx2 and SignerSignEx3 functions. Nothing has a header. This at the top of all of the MSDN articles:

Note This structure is not defined in any header file. To use this structure, you must define it yourself as shown in this topic.

So you very well may be right. However, we have no idea what SIGNER_SIGN_EX3_PARAMS is, or SIGNER_SIGN_EX2_PARAMS, either. None of it is in the Windows SDK. All you can do is copy and paste stuff from MSDN.

The good news is, I have a branch, appx-support where it works, but I am not quite happy with the code quality and there is still some uncertainty I have regarding the reverse engineering.

Owner

vcsjones commented Sep 6, 2017

Where PSIGNER_SIGN_EX3_PARAMS matches the SignerSignEx3 args?

Probably! There is one interesting thing about all of the SignerSignEx2 and SignerSignEx3 functions. Nothing has a header. This at the top of all of the MSDN articles:

Note This structure is not defined in any header file. To use this structure, you must define it yourself as shown in this topic.

So you very well may be right. However, we have no idea what SIGNER_SIGN_EX3_PARAMS is, or SIGNER_SIGN_EX2_PARAMS, either. None of it is in the Windows SDK. All you can do is copy and paste stuff from MSDN.

The good news is, I have a branch, appx-support where it works, but I am not quite happy with the code quality and there is still some uncertainty I have regarding the reverse engineering.

@onovotny

This comment has been minimized.

Show comment
Hide comment
@onovotny

onovotny Sep 6, 2017

Collaborator

cool...so for file extensions, based on the wintrust.dll.ini that's in the sdk directory, there's 4 file extensions it applies to: appx, eappx, appxbundle, eappxbundle.

Do you know if all those libraries, including wintrust with it's ini file, are required to be alongside the tool, or is that already in the OS?

Collaborator

onovotny commented Sep 6, 2017

cool...so for file extensions, based on the wintrust.dll.ini that's in the sdk directory, there's 4 file extensions it applies to: appx, eappx, appxbundle, eappxbundle.

Do you know if all those libraries, including wintrust with it's ini file, are required to be alongside the tool, or is that already in the OS?

@onovotny

This comment has been minimized.

Show comment
Hide comment
@onovotny

onovotny Sep 6, 2017

Collaborator

SIGNER_SIGN_EX2_PARAMS is defined in that article, so I assume it's accurate.

Collaborator

onovotny commented Sep 6, 2017

SIGNER_SIGN_EX2_PARAMS is defined in that article, so I assume it's accurate.

@vcsjones

This comment has been minimized.

Show comment
Hide comment
@vcsjones

vcsjones Sep 6, 2017

Owner

SIGNER_SIGN_EX2_PARAMS is defined in that article

Maybe. There is no article for the "Ex3". Also there are some cases where the MSDN articles are documenting incorrectly. SignTool doesn't seem to follow what the article does either.

Owner

vcsjones commented Sep 6, 2017

SIGNER_SIGN_EX2_PARAMS is defined in that article

Maybe. There is no article for the "Ex3". Also there are some cases where the MSDN articles are documenting incorrectly. SignTool doesn't seem to follow what the article does either.

@onovotny

This comment has been minimized.

Show comment
Hide comment
@onovotny

onovotny Sep 6, 2017

Collaborator

Fair enough :P

Collaborator

onovotny commented Sep 6, 2017

Fair enough :P

@vcsjones

This comment has been minimized.

Show comment
Hide comment
@vcsjones

vcsjones Sep 6, 2017

Owner

Do you know if all those libraries, including wintrust with it's ini file, are required to be alongside the tool, or is that already in the OS?

The branch seems to work without copying any pieces from the SDK.

Owner

vcsjones commented Sep 6, 2017

Do you know if all those libraries, including wintrust with it's ini file, are required to be alongside the tool, or is that already in the OS?

The branch seems to work without copying any pieces from the SDK.

@vcsjones

This comment has been minimized.

Show comment
Hide comment
@vcsjones

vcsjones Sep 6, 2017

Owner

This should be done in the next day or two; want to poke at the struct with WinDbg a bit more and fix some of the crappy memory issues I introduced.

Owner

vcsjones commented Sep 6, 2017

This should be done in the next day or two; want to poke at the struct with WinDbg a bit more and fix some of the crappy memory issues I introduced.

@vcsjones

This comment has been minimized.

Show comment
Hide comment
@vcsjones

vcsjones Sep 6, 2017

Owner

OK. I'm writing this for my own sake to help me understand how I came to the conclusions I am about to post.

Basically, when you use SignerSignEx3, the APPX SIP will call SignerSignEx3 again. In order to do that, the SIP needs the arguments passed in to the first SignerSignEx3 call. It wants this in the pSipData parameter.

We can use WinDbg to set a breakpoint on SignerSignEx3, at which point the pSipData will contain a structure. We can then fill the structure with values to see how they are passed in to the second call of SignerSignEx3.

Here, we have broken on the first call to SignerSignEx3:

(Note: the first column is addresses, the rest are the values)

0:000> dp esp+4
0043d97c    00000410 0043db0c 0043dac4 0043dae8
0043d98c    0043db2c 00000002 01305488 00c52a80
0043d99c    00000000 0043db54 00000000 00000000

We know that pSipData is the 10th parameter, and by matching the memory to the signature call, we see that the 10th parameter has a value of 0043db54.

0:000> dd 0043db54 
0043db54    0043d9dc 00000000

This appears to point to a structure that is described in this MSDN article. So we know the first field is a pointer to the struct we really want to fill out. Conclusion: the APPX_SIP_CLIENT_DATA in the article is still valid for SignerSignEx3.

Things started to look a little weird when we got to the value of 0043d9dc:

0:000> dd 0043d9dc 
0043d9dc    00000410 0043da88 0043da6c 0043d9c4
0043d9ec    00000000 00000002 01305488 00c52a80
0043d9fc    00000000 0043db94 00000000 00000000
0043da0c    00000000 0000000c 00000000 00000000

There are a number of 0 values here. Lets flood them with canary values and see what the second call to SignerSignEx3 looks like.

0:000> dd 0043d9dc
0043d9dc    00000410 0043da88 0043da6c 0043d9c4
0043d9ec    11111111 00000002 01305488 00c52a80
0043d9fc    22222222 0043db94 33333333 44444444
0043da0c    55555555 0000000c 00000000 00000000

Then we do a g, and it doesn't crash (surprise!) we hit SignerSignEx3 again.

0:000> dd esp+4 LE
0043d570    00000410 0043d5c0 0043da6c 0043d9c4
0043d580    11111111 00000002 01305488 00c52a80
0043d590    22222222 0043db54 33333333 44444444
0043d5a0    0043db94 55555555

The above is the arguments to the second SignerSignEx3 call. We can see that it is using the values from our struct, and the canary values we filled in. Since we know the signature of SignerSignEx3, we can map the arguments to the call to the position in the structure.

Both the structure and the call parameters start with 00000410. This is easy, this is the dwFlags.

Let's examine the structure's value:

0:000> dd 0043da88
0043da88  00000010 01337c14 00000001 0043da10

This still looks like a SIGNER_SUBJECT_INFO whose union value is a SIGNER_FILE_INFO. If we examine the value to the file info:

0:000> dd 0043da10
0043da10     0000000c 00000000 00000000 00000058

Well, the structure's size c matches, but it has a null file. Let's look at what is actually used in the call to SignerSignEx3:

0:000> dd 0043d5c0 
0043d5c0    00000010 0043d5d4 00000001 0043d5b4

We know from the signature that this is a SIGNER_SUBJECT_INFO. Let's examine the union's value:

0:000> dd 0043d5b4 L3
0043d5b4  0000000c 09563008 00000000

We don't have a null file path. Let's dump it:

0:000> du 09563008 
09563008    "C:\Users\KEVINJ~1\AppData\Local\"
09563048    "Temp\AXS.9um_5spege6bpjd_09owrgj"
09563088    "0d.cat"

Excellent. So the APPX SIP is signing a catalog file it generated in the temp directory.

Conclusion: the second field in the structure is SIGNER_SUBJECT_INFO*. However, it isn't used for APPX. The APPX SIP makes its own for signing a temporary catalog file.

The third through the ninth fields in the structure also match the parameters in the call, identically. We can conclude then that fields one through nine of the struct are the same as the method signature.

The tenth is interesting. The structure has a value of 0043db94, the SignerSignEx3 call has a value of 0043db54.

Let's examine the structure, first.

0:000> dd 0043db94
0043db94    0000000c 087718d0 00000000 

Hm. That looks interesting. The second thing looks like an address. If we dump raw, we don't get much useful info from it:

0:000> dd 087718d0 
087718d0  53e58955 ec835657 1c458b34 8b184d8b
087718e0  758b1455 0c7d8b10 89085d8b c031c045
087718f0  89c45d89 7589c87d d05589cc 8bd44d89

The range of it is interesting. It doesn't look like a heap or stack address. Maybe it's a function.

0:000> u 087718d0 
akvst!akvst::AuthenticodeDigestSign [C:\dev\Personal\AzureKeyVaultSignTool\src\lib.rs @ 20]:
087718d0 55              push    ebp
087718d1 89e5            mov     ebp,esp
087718d3 53              push    ebx

Aha. And the c value in the first value was the size of a struct. So the structure contains an address to a UNDOCUMENTED_SIGN_CALLBACK structure, it would seem. SignerSignEx3's value appears to point to APPX_SIP_CLIENT_DATA, again.

Conclusion: the 10th field is a UNDOCUMENTED_SIGN_CALLBACK* structure.

Fields 11 and 12 match parameters 11 and 12 with canary values 33333333 and 44444444, respectively.

The 13th argument of the function call matches field 10 of the structure, 0043db94. We know the 13th argument is UNDOCUMENTED_SIGN_CALLBACK* as well, so this supports our previous conclusions.

The 14th arguments matches the 13th field with canary value 55555555. This we can conclude is the pReserved field.

If we put that all together, it would seem this is the correct struct definition:

typedef _SIGNER_SIGN_EX3_PARAMS {
	DWORD dwFlags;
	SIGNER_SUBJECT_INFO* pSubjectInfo;
	SIGNER_CERT* pSigningCert;
	SIGNER_SIGNATURE_INFO* pSignatureInfo;
	SIGNER_PROVIDER_INFO* pProviderInfo;
	DWORD dwTimestampFlags;
	PCSTR pszTimestampAlgorithmOid;
	PCWSTR pwszTimestampURL;
	CRYPT_ATTRIBUTES* psRequest;
	SIGN_INFO* signCallbackInfo;
	SIGNER_CONTEXT** ppSignerContext;
	CERT_STRONG_SIGN_PARA* pCryptoPolicy;
	PVOID pReserved;
} SIGNER_SIGN_EX3_PARAMS;

This ends up being real close to the SIGNER_SIGN_EX2_PARAMS, aside from the APPX SIP not using how they document it in the example. The difference appears to be swapping out the SIP data from pointing to itself to the new callback model.

I have not investigated the behavior of this when flag 0x400 is not passed in.

Another thing learned: APPX requires passing in the 0x10 flag, which is page hashing. This flag will always be used by signtool even if the flag is not specified.

Owner

vcsjones commented Sep 6, 2017

OK. I'm writing this for my own sake to help me understand how I came to the conclusions I am about to post.

Basically, when you use SignerSignEx3, the APPX SIP will call SignerSignEx3 again. In order to do that, the SIP needs the arguments passed in to the first SignerSignEx3 call. It wants this in the pSipData parameter.

We can use WinDbg to set a breakpoint on SignerSignEx3, at which point the pSipData will contain a structure. We can then fill the structure with values to see how they are passed in to the second call of SignerSignEx3.

Here, we have broken on the first call to SignerSignEx3:

(Note: the first column is addresses, the rest are the values)

0:000> dp esp+4
0043d97c    00000410 0043db0c 0043dac4 0043dae8
0043d98c    0043db2c 00000002 01305488 00c52a80
0043d99c    00000000 0043db54 00000000 00000000

We know that pSipData is the 10th parameter, and by matching the memory to the signature call, we see that the 10th parameter has a value of 0043db54.

0:000> dd 0043db54 
0043db54    0043d9dc 00000000

This appears to point to a structure that is described in this MSDN article. So we know the first field is a pointer to the struct we really want to fill out. Conclusion: the APPX_SIP_CLIENT_DATA in the article is still valid for SignerSignEx3.

Things started to look a little weird when we got to the value of 0043d9dc:

0:000> dd 0043d9dc 
0043d9dc    00000410 0043da88 0043da6c 0043d9c4
0043d9ec    00000000 00000002 01305488 00c52a80
0043d9fc    00000000 0043db94 00000000 00000000
0043da0c    00000000 0000000c 00000000 00000000

There are a number of 0 values here. Lets flood them with canary values and see what the second call to SignerSignEx3 looks like.

0:000> dd 0043d9dc
0043d9dc    00000410 0043da88 0043da6c 0043d9c4
0043d9ec    11111111 00000002 01305488 00c52a80
0043d9fc    22222222 0043db94 33333333 44444444
0043da0c    55555555 0000000c 00000000 00000000

Then we do a g, and it doesn't crash (surprise!) we hit SignerSignEx3 again.

0:000> dd esp+4 LE
0043d570    00000410 0043d5c0 0043da6c 0043d9c4
0043d580    11111111 00000002 01305488 00c52a80
0043d590    22222222 0043db54 33333333 44444444
0043d5a0    0043db94 55555555

The above is the arguments to the second SignerSignEx3 call. We can see that it is using the values from our struct, and the canary values we filled in. Since we know the signature of SignerSignEx3, we can map the arguments to the call to the position in the structure.

Both the structure and the call parameters start with 00000410. This is easy, this is the dwFlags.

Let's examine the structure's value:

0:000> dd 0043da88
0043da88  00000010 01337c14 00000001 0043da10

This still looks like a SIGNER_SUBJECT_INFO whose union value is a SIGNER_FILE_INFO. If we examine the value to the file info:

0:000> dd 0043da10
0043da10     0000000c 00000000 00000000 00000058

Well, the structure's size c matches, but it has a null file. Let's look at what is actually used in the call to SignerSignEx3:

0:000> dd 0043d5c0 
0043d5c0    00000010 0043d5d4 00000001 0043d5b4

We know from the signature that this is a SIGNER_SUBJECT_INFO. Let's examine the union's value:

0:000> dd 0043d5b4 L3
0043d5b4  0000000c 09563008 00000000

We don't have a null file path. Let's dump it:

0:000> du 09563008 
09563008    "C:\Users\KEVINJ~1\AppData\Local\"
09563048    "Temp\AXS.9um_5spege6bpjd_09owrgj"
09563088    "0d.cat"

Excellent. So the APPX SIP is signing a catalog file it generated in the temp directory.

Conclusion: the second field in the structure is SIGNER_SUBJECT_INFO*. However, it isn't used for APPX. The APPX SIP makes its own for signing a temporary catalog file.

The third through the ninth fields in the structure also match the parameters in the call, identically. We can conclude then that fields one through nine of the struct are the same as the method signature.

The tenth is interesting. The structure has a value of 0043db94, the SignerSignEx3 call has a value of 0043db54.

Let's examine the structure, first.

0:000> dd 0043db94
0043db94    0000000c 087718d0 00000000 

Hm. That looks interesting. The second thing looks like an address. If we dump raw, we don't get much useful info from it:

0:000> dd 087718d0 
087718d0  53e58955 ec835657 1c458b34 8b184d8b
087718e0  758b1455 0c7d8b10 89085d8b c031c045
087718f0  89c45d89 7589c87d d05589cc 8bd44d89

The range of it is interesting. It doesn't look like a heap or stack address. Maybe it's a function.

0:000> u 087718d0 
akvst!akvst::AuthenticodeDigestSign [C:\dev\Personal\AzureKeyVaultSignTool\src\lib.rs @ 20]:
087718d0 55              push    ebp
087718d1 89e5            mov     ebp,esp
087718d3 53              push    ebx

Aha. And the c value in the first value was the size of a struct. So the structure contains an address to a UNDOCUMENTED_SIGN_CALLBACK structure, it would seem. SignerSignEx3's value appears to point to APPX_SIP_CLIENT_DATA, again.

Conclusion: the 10th field is a UNDOCUMENTED_SIGN_CALLBACK* structure.

Fields 11 and 12 match parameters 11 and 12 with canary values 33333333 and 44444444, respectively.

The 13th argument of the function call matches field 10 of the structure, 0043db94. We know the 13th argument is UNDOCUMENTED_SIGN_CALLBACK* as well, so this supports our previous conclusions.

The 14th arguments matches the 13th field with canary value 55555555. This we can conclude is the pReserved field.

If we put that all together, it would seem this is the correct struct definition:

typedef _SIGNER_SIGN_EX3_PARAMS {
	DWORD dwFlags;
	SIGNER_SUBJECT_INFO* pSubjectInfo;
	SIGNER_CERT* pSigningCert;
	SIGNER_SIGNATURE_INFO* pSignatureInfo;
	SIGNER_PROVIDER_INFO* pProviderInfo;
	DWORD dwTimestampFlags;
	PCSTR pszTimestampAlgorithmOid;
	PCWSTR pwszTimestampURL;
	CRYPT_ATTRIBUTES* psRequest;
	SIGN_INFO* signCallbackInfo;
	SIGNER_CONTEXT** ppSignerContext;
	CERT_STRONG_SIGN_PARA* pCryptoPolicy;
	PVOID pReserved;
} SIGNER_SIGN_EX3_PARAMS;

This ends up being real close to the SIGNER_SIGN_EX2_PARAMS, aside from the APPX SIP not using how they document it in the example. The difference appears to be swapping out the SIP data from pointing to itself to the new callback model.

I have not investigated the behavior of this when flag 0x400 is not passed in.

Another thing learned: APPX requires passing in the 0x10 flag, which is page hashing. This flag will always be used by signtool even if the flag is not specified.

@onovotny

This comment has been minimized.

Show comment
Hide comment
@onovotny

onovotny Sep 6, 2017

Collaborator

@vcsjones that's brilliant engineering!

Collaborator

onovotny commented Sep 6, 2017

@vcsjones that's brilliant engineering!

@vcsjones vcsjones referenced this issue Sep 7, 2017

Merged

Appx support #4

@vcsjones vcsjones closed this in #4 Sep 7, 2017

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment