Skip to content

Commit acd3dad

Browse files
committed
Remove interop code as much as possible
1 parent 5a2e35a commit acd3dad

11 files changed

Lines changed: 154 additions & 390 deletions

Directory.Packages.props

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
<PackageVersion Include="Microsoft.Extensions.FileSystemGlobbing" Version="8.0.0" />
77
<PackageVersion Include="Microsoft.Extensions.Logging" Version="8.0.1" />
88
<PackageVersion Include="Microsoft.Extensions.Logging.Console" Version="8.0.1" />
9+
<PackageVersion Include="Microsoft.Windows.CsWin32" Version="0.3.162" />
910

1011
<PackageVersion Include="System.Net.Http" Version="4.3.4" />
1112
<PackageVersion Include="System.Text.Json" Version="8.0.5" />

nuget.config

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<configuration>
3+
<packageSources>
4+
<!--To inherit the global NuGet package sources remove the <clear/> line below -->
5+
<clear />
6+
<add key="nuget" value="https://api.nuget.org/v3/index.json" />
7+
</packageSources>
8+
</configuration>

src/AzureSign.Core/AlgorithmTranslator.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,14 @@ public static uint HashAlgorithmToAlgId(HashAlgorithmName hashAlgorithmName)
1717
};
1818
}
1919

20-
public static ReadOnlySpan<byte> HashAlgorithmToOidAsciiTerminated(HashAlgorithmName hashAlgorithmName)
20+
public static string HashAlgorithmToOidAsciiTerminated(HashAlgorithmName hashAlgorithmName)
2121
{
2222
return hashAlgorithmName.Name switch
2323
{
24-
nameof(HashAlgorithmName.SHA1) => "1.3.14.3.2.26\0"u8,
25-
nameof(HashAlgorithmName.SHA256) => "2.16.840.1.101.3.4.2.1\0"u8,
26-
nameof(HashAlgorithmName.SHA384) => "2.16.840.1.101.3.4.2.2\0"u8,
27-
nameof(HashAlgorithmName.SHA512) => "2.16.840.1.101.3.4.2.3\0"u8,
24+
nameof(HashAlgorithmName.SHA1) => "1.3.14.3.2.26\0",
25+
nameof(HashAlgorithmName.SHA256) => "2.16.840.1.101.3.4.2.1\0",
26+
nameof(HashAlgorithmName.SHA384) => "2.16.840.1.101.3.4.2.2\0",
27+
nameof(HashAlgorithmName.SHA512) => "2.16.840.1.101.3.4.2.3\0",
2828
_ => throw new NotSupportedException("The algorithm specified is not supported."),
2929
};
3030
}

src/AzureSign.Core/AuthenticodeKeyVaultSigner.cs

Lines changed: 102 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
1+
using static Windows.Win32.PInvoke;
2+
using Windows.Win32.Foundation;
13
using AzureSign.Core.Interop;
24
using Microsoft.Extensions.Logging;
35
using System;
46
using System.Diagnostics;
57
using System.Runtime.InteropServices;
68
using System.Security.Cryptography;
79
using System.Security.Cryptography.X509Certificates;
10+
using Windows.Win32.Security.Cryptography;
811

912
namespace AzureSign.Core
1013
{
@@ -87,15 +90,15 @@ static char[] NullTerminate(ReadOnlySpan<char> str)
8790
return result;
8891
}
8992

90-
SignerSignEx3Flags flags = SignerSignEx3Flags.SIGN_CALLBACK_UNDOCUMENTED;
93+
SIGNER_SIGN_FLAGS flags = SIGNER_SIGN_FLAGS.SPC_DIGEST_SIGN_FLAG;
9194

9295
if (pageHashing == true)
9396
{
94-
flags |= SignerSignEx3Flags.SPC_INC_PE_PAGE_HASHES_FLAG;
97+
flags |= SIGNER_SIGN_FLAGS.SPC_INC_PE_PAGE_HASHES_FLAG;
9598
}
9699
else if (pageHashing == false)
97100
{
98-
flags |= SignerSignEx3Flags.SPC_EXC_PE_PAGE_HASHES_FLAG;
101+
flags |= SIGNER_SIGN_FLAGS.SPC_EXC_PE_PAGE_HASHES_FLAG;
99102
}
100103

101104
if (appendSignature)
@@ -106,66 +109,106 @@ static char[] NullTerminate(ReadOnlySpan<char> str)
106109
logger?.LogWarning("If you set the dwTimestampFlags parameter to SIGNER_TIMESTAMP_AUTHENTICODE, you cannot set the dwFlags parameter to SIG_APPEND.");
107110
}
108111

109-
flags |= SignerSignEx3Flags.SIG_APPEND;
112+
flags |= SIGNER_SIGN_FLAGS.SIG_APPEND;
110113
}
111114

112-
SignerSignTimeStampFlags timeStampFlags;
113-
ReadOnlySpan<byte> timestampAlgorithmOid;
115+
SIGNER_TIMESTAMP_FLAGS timeStampFlags;
116+
string? timestampAlgorithmOid = null;
114117
string? timestampUrl;
115118

116119
switch (_timeStampConfiguration.Type)
117120
{
118121
case TimeStampType.Authenticode:
119-
timeStampFlags = SignerSignTimeStampFlags.SIGNER_TIMESTAMP_AUTHENTICODE;
120-
timestampAlgorithmOid = default;
122+
timeStampFlags = SIGNER_TIMESTAMP_FLAGS.SIGNER_TIMESTAMP_AUTHENTICODE;
121123
timestampUrl = _timeStampConfiguration.Url;
122124
break;
123125
case TimeStampType.RFC3161:
124-
timeStampFlags = SignerSignTimeStampFlags.SIGNER_TIMESTAMP_RFC3161;
126+
timeStampFlags = SIGNER_TIMESTAMP_FLAGS.SIGNER_TIMESTAMP_RFC3161;
125127
timestampAlgorithmOid = AlgorithmTranslator.HashAlgorithmToOidAsciiTerminated(_timeStampConfiguration.DigestAlgorithm);
126128
timestampUrl = _timeStampConfiguration.Url;
127129
break;
128130
default:
129131
timeStampFlags = default;
130-
timestampAlgorithmOid = default;
131132
timestampUrl = null;
132133
break;
133134
}
134135

135-
fixed (byte* pTimestampAlgorithm = timestampAlgorithmOid)
136136
fixed (char* pTimestampUrl = timestampUrl)
137137
fixed (char* pPath = NullTerminate(path))
138138
fixed (char* pDescription = NullTerminate(description))
139139
fixed (char* pDescriptionUrl = NullTerminate(descriptionUrl))
140140
{
141-
var fileInfo = new SIGNER_FILE_INFO(pPath, default);
141+
var fileInfo = new SIGNER_FILE_INFO()
142+
{
143+
cbSize = (uint)Marshal.SizeOf<SIGNER_FILE_INFO>(),
144+
hFile = default,
145+
pwszFileName = pPath,
146+
};
142147
var subjectIndex = 0u;
143-
var signerSubjectInfoUnion = new SIGNER_SUBJECT_INFO_UNION(&fileInfo);
144-
var subjectInfo = new SIGNER_SUBJECT_INFO(&subjectIndex, SignerSubjectInfoUnionChoice.SIGNER_SUBJECT_FILE, signerSubjectInfoUnion);
145-
var authCodeStructure = new SIGNER_ATTR_AUTHCODE(pDescription, pDescriptionUrl);
146-
var storeInfo = new SIGNER_CERT_STORE_INFO(
147-
dwCertPolicy: SignerCertStoreInfoFlags.SIGNER_CERT_POLICY_CHAIN,
148-
hCertStore: _certificateStore.Handle,
149-
pSigningCert: _signingCertificate.Handle
150-
);
151-
var signerCert = new SIGNER_CERT(
152-
dwCertChoice: SignerCertChoice.SIGNER_CERT_STORE,
153-
union: new SIGNER_CERT_UNION(&storeInfo)
154-
);
155-
var signatureInfo = new SIGNER_SIGNATURE_INFO(
156-
algidHash: AlgorithmTranslator.HashAlgorithmToAlgId(_fileDigestAlgorithm),
157-
psAuthenticated: IntPtr.Zero,
158-
psUnauthenticated: IntPtr.Zero,
159-
dwAttrChoice: SignerSignatureInfoAttrChoice.SIGNER_AUTHCODE_ATTR,
160-
attrAuthUnion: new SIGNER_SIGNATURE_INFO_UNION(&authCodeStructure)
161-
);
148+
var subjectInfo = new SIGNER_SUBJECT_INFO
149+
{
150+
cbSize = (uint)Marshal.SizeOf<SIGNER_SUBJECT_INFO>(),
151+
pdwIndex = &subjectIndex,
152+
dwSubjectChoice = SIGNER_SUBJECT_CHOICE.SIGNER_SUBJECT_FILE,
153+
Anonymous = new() { pSignerFileInfo = &fileInfo }
154+
};
155+
var authCodeStructure = new SIGNER_ATTR_AUTHCODE
156+
{
157+
cbSize = (uint)Marshal.SizeOf<SIGNER_ATTR_AUTHCODE>(),
158+
fCommercial = false,
159+
fIndividual = false,
160+
pwszName = pDescription,
161+
pwszInfo = pDescriptionUrl,
162+
163+
};
164+
165+
var storeInfo = new SIGNER_CERT_STORE_INFO
166+
{
167+
cbSize = (uint)Marshal.SizeOf<SIGNER_CERT_STORE_INFO>(),
168+
dwCertPolicy = SIGNER_CERT_POLICY.SIGNER_CERT_POLICY_CHAIN,
169+
hCertStore = _certificateStore.Handle,
170+
pSigningCert = (CERT_CONTEXT*)_signingCertificate.Handle
171+
};
172+
173+
var signerCert = new SIGNER_CERT()
174+
{
175+
cbSize = (uint)Marshal.SizeOf<SIGNER_CERT>(),
176+
dwCertChoice = SIGNER_CERT_CHOICE.SIGNER_CERT_STORE,
177+
Anonymous = new() { pCertStoreInfo = &storeInfo },
178+
};
179+
180+
var signatureInfo = new SIGNER_SIGNATURE_INFO
181+
{
182+
cbSize = (uint)Marshal.SizeOf<SIGNER_SIGNATURE_INFO>(),
183+
algidHash = (ALG_ID)AlgorithmTranslator.HashAlgorithmToAlgId(_fileDigestAlgorithm),
184+
psAuthenticated = null,
185+
psUnauthenticated = null,
186+
dwAttrChoice = SIGNER_SIGNATURE_ATTRIBUTE_CHOICE.SIGNER_AUTHCODE_ATTR,
187+
Anonymous = new() { pAttrAuthcode = &authCodeStructure }
188+
};
189+
162190
var callbackPtr = Marshal.GetFunctionPointerForDelegate(_signCallback);
163-
var signCallbackInfo = new SIGN_INFO(callbackPtr);
191+
var signCallbackInfo = new SIGNER_DIGEST_SIGN_INFO
192+
{
193+
cbSize = 24,
194+
Anonymous = new()
195+
{
196+
pfnAuthenticodeDigestSign =
197+
(delegate* unmanaged[Stdcall]<
198+
CERT_CONTEXT*,
199+
CRYPT_INTEGER_BLOB*,
200+
ALG_ID,
201+
byte*,
202+
uint,
203+
CRYPT_INTEGER_BLOB*, HRESULT>)
204+
callbackPtr
205+
},
206+
};
164207

165208
logger?.LogTrace("Getting SIP Data");
166209
var sipKind = SipExtensionFactory.GetSipKind(path);
167210
void* sipData = (void*)0;
168-
IntPtr context = IntPtr.Zero;
211+
SIGNER_CONTEXT* pContext = null;
169212

170213
switch (sipKind)
171214
{
@@ -174,35 +217,34 @@ static char[] NullTerminate(ReadOnlySpan<char> str)
174217
SIGNER_SIGN_EX3_PARAMS parameters;
175218
clientData.pSignerParams = &parameters;
176219
sipData = &clientData;
177-
flags &= ~SignerSignEx3Flags.SPC_INC_PE_PAGE_HASHES_FLAG;
178-
flags |= SignerSignEx3Flags.SPC_EXC_PE_PAGE_HASHES_FLAG;
179-
FillAppxExtension(ref clientData, flags, timeStampFlags, &subjectInfo, &signerCert, &signatureInfo, &context, pTimestampUrl, pTimestampAlgorithm, &signCallbackInfo);
220+
flags &= ~SIGNER_SIGN_FLAGS.SPC_INC_PE_PAGE_HASHES_FLAG;
221+
flags |= SIGNER_SIGN_FLAGS.SPC_EXC_PE_PAGE_HASHES_FLAG;
222+
FillAppxExtension(ref clientData, flags, timeStampFlags, &subjectInfo, &signerCert, &signatureInfo, pContext, pTimestampUrl, timestampAlgorithmOid, &signCallbackInfo);
180223
break;
181224
}
182225

183226
logger?.LogTrace($"Calling SignerSignEx3 with flags: {flags}");
184-
var result = mssign32.SignerSignEx3
227+
var result = SignerSignEx3
185228
(
186229
flags,
187-
&subjectInfo,
188-
&signerCert,
189-
&signatureInfo,
190-
IntPtr.Zero,
230+
subjectInfo,
231+
signerCert,
232+
signatureInfo,
233+
null,
191234
timeStampFlags,
192-
pTimestampAlgorithm,
193-
pTimestampUrl,
194-
IntPtr.Zero,
235+
timestampAlgorithmOid,
236+
timestampUrl,
237+
null,
195238
sipData,
196-
&context,
197-
IntPtr.Zero,
198-
&signCallbackInfo,
199-
IntPtr.Zero
239+
out pContext,
240+
null,
241+
signCallbackInfo
200242
);
201-
if (result == 0 && context != IntPtr.Zero)
243+
if (result == HRESULT.S_OK && pContext != null)
202244
{
203-
Debug.Assert(mssign32.SignerFreeSignerContext(context) == 0);
245+
Debug.Assert(SignerFreeSignerContext(pContext) == HRESULT.S_OK);
204246
}
205-
if (result == 0 && sipKind == SipKind.Appx)
247+
if (result == HRESULT.S_OK && sipKind == SipKind.Appx)
206248
{
207249
var state = ((APPX_SIP_CLIENT_DATA*)sipData)->pAppxSipState;
208250
if (state != IntPtr.Zero)
@@ -229,10 +271,9 @@ private unsafe int SignCallback(
229271
uint algId,
230272
byte[] pDigestToSign,
231273
uint dwDigestToSign,
232-
ref CRYPTOAPI_BLOB blob
274+
ref CRYPT_INTEGER_BLOB blob
233275
)
234276
{
235-
const int E_INVALIDARG = unchecked((int)0x80070057);
236277
byte[] digest;
237278
switch (_signingAlgorithm)
238279
{
@@ -243,26 +284,26 @@ ref CRYPTOAPI_BLOB blob
243284
digest = ecdsa.SignHash(pDigestToSign);
244285
break;
245286
default:
246-
return E_INVALIDARG;
287+
return HRESULT.E_INVALIDARG;
247288
}
248289
var resultPtr = Marshal.AllocHGlobal(digest.Length);
249290
Marshal.Copy(digest, 0, resultPtr, digest.Length);
250-
blob.pbData = resultPtr;
291+
blob.pbData = (byte*)resultPtr;
251292
blob.cbData = (uint)digest.Length;
252-
return 0;
293+
return HRESULT.S_OK;
253294
}
254295

255296
private static unsafe void FillAppxExtension(
256297
ref APPX_SIP_CLIENT_DATA clientData,
257-
SignerSignEx3Flags flags,
258-
SignerSignTimeStampFlags timestampFlags,
298+
SIGNER_SIGN_FLAGS flags,
299+
SIGNER_TIMESTAMP_FLAGS timestampFlags,
259300
SIGNER_SUBJECT_INFO* signerSubjectInfo,
260301
SIGNER_CERT* signerCert,
261302
SIGNER_SIGNATURE_INFO* signatureInfo,
262-
IntPtr* signerContext,
303+
SIGNER_CONTEXT* signerContext,
263304
char* timestampUrl,
264-
byte* timestampOid,
265-
SIGN_INFO* signInfo
305+
string? timestampOid,
306+
SIGNER_DIGEST_SIGN_INFO* signInfo
266307
)
267308
{
268309
clientData.pSignerParams->dwFlags = flags;

src/AzureSign.Core/AzureSign.Core.csproj

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,7 @@
1616

1717
<ItemGroup>
1818
<PackageReference Include="Microsoft.Extensions.Logging" />
19-
<PackageReference Include="MinVer">
20-
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
21-
<PrivateAssets>all</PrivateAssets>
22-
</PackageReference>
19+
<PackageReference Include="Microsoft.Windows.CsWin32" PrivateAssets="All" IncludeAssets="runtime; build; native; contentfiles; analyzers; buildtransitive" />
2320
</ItemGroup>
2421

2522
</Project>

0 commit comments

Comments
 (0)