@tsplc/build 0.0.0-stage → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +6 -2
  3. package/dist/cli.js +1696 -0
  4. package/dist/cli.js.map +34 -0
  5. package/dist/index.js +1683 -0
  6. package/dist/index.js.map +31 -0
  7. package/dist/libraries.js +128 -0
  8. package/dist/libraries.js.map +10 -0
  9. package/docker/Dockerfile +173 -0
  10. package/docker/Dockerfile.dockerignore +18 -0
  11. package/docker/Dockerfile.source +15 -0
  12. package/docker/build-image +38 -0
  13. package/docker/codesys-build +5 -0
  14. package/docker/config.ts +8 -0
  15. package/docker/control-linux-sl/Dockerfile +38 -0
  16. package/docker/edge-gateway/Dockerfile +17 -0
  17. package/docker/entrypoint.sh +10 -0
  18. package/docker/install/NOTICE.md +21 -0
  19. package/docker/install/core.sh +36 -0
  20. package/docker/install/decode.c +12 -0
  21. package/docker/install/device/Runtime.ico +0 -0
  22. package/docker/install/device/Runtime.png +0 -0
  23. package/docker/install/device/codesyscontrol.devdesc.xml +1502 -0
  24. package/docker/install/extract.py +43 -0
  25. package/docker/install/helper-launcher.c +46 -0
  26. package/docker/install/install.sh +94 -0
  27. package/docker/install/prerequisites.sh +15 -0
  28. package/docker/install/verify.py +133 -0
  29. package/docker/install/verify.sh +34 -0
  30. package/docker/install/wine-ncrypt/COPYING.LIB +502 -0
  31. package/docker/install/wine-ncrypt/README.md +28 -0
  32. package/docker/install/wine-ncrypt/enable-oaep.py +34 -0
  33. package/docker/install/wine-ncrypt/main.c +619 -0
  34. package/docker/install/wine-ncrypt/oaep.patch +11 -0
  35. package/docker/install/wine-signal/README.md +22 -0
  36. package/docker/install/wine-signal/build.sh +10 -0
  37. package/docker/install/wine-signal/check.sh +34 -0
  38. package/docker/install/wine-signal/noop-i386.c +2 -0
  39. package/docker/install/wine-signal/signal-state.c +105 -0
  40. package/docker/install/wine-signal/tests/avx-registers.c +53 -0
  41. package/docker/install/wine-signal/tests/frame-and-handler.c +192 -0
  42. package/docker/install/wine-signal/tests/loader-i386.c +8 -0
  43. package/docker/install/wine-signal/tests/signal-return.c +47 -0
  44. package/docker/install/wine-signal/wine +4 -0
  45. package/docker/runner.ts +156 -0
  46. package/package.json +53 -4
  47. package/python/build.py +660 -0
  48. package/python/codesys_login.py +100 -0
  49. package/python/codesys_online.py +327 -0
  50. package/python/test_build.py +444 -0
  51. package/python/test_codesys_login.py +120 -0
  52. package/python/test_codesys_online.py +184 -0
  53. package/python/test_installer_packages.py +216 -0
  54. package/python/test_installer_verification.py +307 -0
  55. package/python/test_worker.py +142 -0
  56. package/python/worker.py +102 -0
  57. package/runtime/install.sh +74 -0
  58. package/src/__tests__/fixtures/xml/fb-simple.xml +40 -0
  59. package/src/__tests__/fixtures/xml/fb-state-machine.xml +86 -0
  60. package/src/__tests__/fixtures/xml/prg-cyclic.xml +44 -0
  61. package/src/artifacts.ts +77 -0
  62. package/src/build.ts +87 -0
  63. package/src/cli.ts +116 -0
  64. package/src/config.ts +12 -0
  65. package/src/controller-online.ts +297 -0
  66. package/src/controller-session.ts +298 -0
  67. package/src/diagnostics.ts +68 -0
  68. package/src/docker-build.ts +163 -0
  69. package/src/docker-context.ts +35 -0
  70. package/src/docker-run.ts +103 -0
  71. package/src/host/codesys-command.ts +45 -0
  72. package/src/host/codesys-host.ts +145 -0
  73. package/src/host/codesys-worker.ts +348 -0
  74. package/src/host/windows-path.ts +73 -0
  75. package/src/index.ts +43 -0
  76. package/src/io.ts +127 -0
  77. package/src/libraries.ts +166 -0
  78. package/src/package-path.ts +5 -0
  79. package/src/run.ts +133 -0
  80. package/src/runtime-status.ts +21 -0
  81. package/src/sources.ts +248 -0
  82. package/src/st/declarations.ts +229 -0
  83. package/src/st/lexer.ts +125 -0
  84. package/src/st/parse.ts +202 -0
  85. package/src/st/reader.ts +50 -0
@@ -0,0 +1,619 @@
1
+ /*
2
+ * New cryptographic library (ncrypt.dll)
3
+ *
4
+ * Copyright 2016 Alex Henrie
5
+ *
6
+ * This library is free software; you can redistribute it and/or
7
+ * modify it under the terms of the GNU Lesser General Public
8
+ * License as published by the Free Software Foundation; either
9
+ * version 2.1 of the License, or (at your option) any later version.
10
+ *
11
+ * This library is distributed in the hope that it will be useful,
12
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
+ * Lesser General Public License for more details.
15
+ *
16
+ * You should have received a copy of the GNU Lesser General Public
17
+ * License along with this library; if not, write to the Free Software
18
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19
+ */
20
+
21
+ #include <stdarg.h>
22
+ #include <stdlib.h>
23
+
24
+ #include "ntstatus.h"
25
+ #include "windef.h"
26
+ #include "winbase.h"
27
+ #include "ncrypt.h"
28
+ #include "bcrypt.h"
29
+ #include "ncrypt_internal.h"
30
+ #include "wine/debug.h"
31
+
32
+ WINE_DEFAULT_DEBUG_CHANNEL(ncrypt);
33
+
34
+ static SECURITY_STATUS map_ntstatus(NTSTATUS status)
35
+ {
36
+ switch (status)
37
+ {
38
+ case STATUS_INVALID_HANDLE: return NTE_INVALID_HANDLE;
39
+ case STATUS_INVALID_SIGNATURE: return NTE_BAD_SIGNATURE;
40
+ case STATUS_SUCCESS: return ERROR_SUCCESS;
41
+ case STATUS_INVALID_PARAMETER: return NTE_INVALID_PARAMETER;
42
+ case STATUS_NO_MEMORY: return NTE_NO_MEMORY;
43
+ case STATUS_NOT_SUPPORTED: return NTE_NOT_SUPPORTED;
44
+ case NTE_BAD_DATA: return NTE_BAD_DATA;
45
+ case STATUS_BUFFER_TOO_SMALL: return NTE_BUFFER_TOO_SMALL;
46
+ default:
47
+ FIXME("unhandled status %#lx\n", status);
48
+ return NTE_INTERNAL_ERROR;
49
+ }
50
+ }
51
+
52
+ static struct object *allocate_object(enum object_type type)
53
+ {
54
+ struct object *ret;
55
+ if (!(ret = calloc(1, sizeof(*ret)))) return NULL;
56
+ ret->type = type;
57
+ ret->refs = 1;
58
+ return ret;
59
+ }
60
+
61
+ static void provider_addref(NCRYPT_PROV_HANDLE handle)
62
+ {
63
+ struct object *object = (struct object *)handle;
64
+ InterlockedIncrement(&object->refs);
65
+ }
66
+
67
+ static struct object_property *get_object_property(struct object *object, const WCHAR *name)
68
+ {
69
+ unsigned int i;
70
+ for (i = 0; i < object->num_properties; i++)
71
+ {
72
+ struct object_property *property = &object->properties[i];
73
+ if (!lstrcmpW(property->key, name)) return property;
74
+ }
75
+ return NULL;
76
+ }
77
+
78
+ struct object_property *add_object_property(struct object *object, const WCHAR *name)
79
+ {
80
+ struct object_property *property;
81
+
82
+ if (!object->num_properties)
83
+ {
84
+ if (!(object->properties = malloc(sizeof(*property))))
85
+ {
86
+ ERR("Error allocating memory.\n");
87
+ return NULL;
88
+ }
89
+ property = &object->properties[object->num_properties++];
90
+ }
91
+ else
92
+ {
93
+ struct object_property *tmp;
94
+ if (!(tmp = realloc(object->properties, sizeof(*property) * (object->num_properties + 1))))
95
+ {
96
+ ERR("Error allocating memory.\n");
97
+ return NULL;
98
+ }
99
+ object->properties = tmp;
100
+ property = &object->properties[object->num_properties++];
101
+ }
102
+
103
+ memset(property, 0, sizeof(*property));
104
+ if (!(property->key = wcsdup(name)))
105
+ {
106
+ ERR("Error allocating memory.\n");
107
+ return NULL;
108
+ }
109
+
110
+ return property;
111
+ }
112
+
113
+ static SECURITY_STATUS set_object_property(struct object *object, const WCHAR *name, BYTE *value, DWORD value_size)
114
+ {
115
+ struct object_property *property = get_object_property(object, name);
116
+ void *tmp;
117
+
118
+ if (!property && !(property = add_object_property(object, name))) return NTE_NO_MEMORY;
119
+
120
+ property->value_size = value_size;
121
+ if (!(tmp = realloc(property->value, value_size)))
122
+ {
123
+ ERR("Error allocating memory.\n");
124
+ free(property->key);
125
+ property->key = NULL;
126
+ return NTE_NO_MEMORY;
127
+ }
128
+
129
+ property->value = tmp;
130
+ memcpy(property->value, value, value_size);
131
+
132
+ return ERROR_SUCCESS;
133
+ }
134
+
135
+ static struct object *create_key_object(enum algid algid, NCRYPT_PROV_HANDLE provider)
136
+ {
137
+ NCRYPT_SUPPORTED_LENGTHS supported_lengths = {512, 16384, 8, 1024};
138
+ struct object *object;
139
+ DWORD dw_value;
140
+
141
+ switch (algid)
142
+ {
143
+ case RSA:
144
+ if (!(object = allocate_object(KEY))) return NULL;
145
+
146
+ object->key.algid = RSA;
147
+ set_object_property(object, NCRYPT_ALGORITHM_PROPERTY, (BYTE *)BCRYPT_RSA_ALGORITHM,
148
+ sizeof(BCRYPT_RSA_ALGORITHM));
149
+ set_object_property(object, NCRYPT_ALGORITHM_GROUP_PROPERTY, (BYTE *)BCRYPT_RSA_ALGORITHM,
150
+ sizeof(BCRYPT_RSA_ALGORITHM));
151
+ set_object_property(object, NCRYPT_LENGTHS_PROPERTY, (BYTE *)&supported_lengths,
152
+ sizeof(supported_lengths));
153
+ dw_value = 128;
154
+ set_object_property(object, NCRYPT_BLOCK_LENGTH_PROPERTY, (BYTE *)&dw_value, sizeof(dw_value));
155
+ dw_value = 128;
156
+ set_object_property(object, BCRYPT_SIGNATURE_LENGTH, (BYTE *)&dw_value, sizeof(dw_value));
157
+ break;
158
+
159
+ case ECDSA_P256:
160
+ if (!(object = allocate_object(KEY))) return NULL;
161
+
162
+ object->key.algid = ECDSA_P256;
163
+ break;
164
+
165
+ default:
166
+ ERR("Invalid algid %#x\n", algid);
167
+ return NULL;
168
+ }
169
+
170
+ dw_value = 0;
171
+ set_object_property(object, NCRYPT_EXPORT_POLICY_PROPERTY, (BYTE *)&dw_value, sizeof(dw_value));
172
+ dw_value = NCRYPT_ALLOW_ALL_USAGES;
173
+ set_object_property(object, NCRYPT_KEY_USAGE_PROPERTY, (BYTE *)&dw_value, sizeof(dw_value));
174
+ dw_value = 0;
175
+ set_object_property(object, NCRYPT_KEY_TYPE_PROPERTY, (BYTE *)&dw_value, sizeof(dw_value));
176
+ provider_addref(provider);
177
+ set_object_property(object, NCRYPT_PROVIDER_HANDLE_PROPERTY, (BYTE *)&provider, sizeof(provider));
178
+ return object;
179
+ }
180
+
181
+ SECURITY_STATUS WINAPI NCryptCreatePersistedKey(NCRYPT_PROV_HANDLE provider, NCRYPT_KEY_HANDLE *key,
182
+ const WCHAR *algid, const WCHAR *name, DWORD keyspec, DWORD flags)
183
+ {
184
+ struct object *object;
185
+
186
+ TRACE("(%#Ix, %p, %s, %s, %#lx, %#lx)\n", provider, key, wine_dbgstr_w(algid),
187
+ wine_dbgstr_w(name), keyspec, flags);
188
+
189
+ if (!provider) return NTE_INVALID_HANDLE;
190
+ if (!algid) return HRESULT_FROM_WIN32(RPC_X_NULL_REF_POINTER);
191
+ if (name) FIXME("Persistent keys are not supported\n");
192
+
193
+ if (!lstrcmpiW(algid, BCRYPT_RSA_ALGORITHM))
194
+ {
195
+ NTSTATUS status;
196
+ DWORD default_bitlen = 1024;
197
+
198
+ if (!(object = create_key_object(RSA, provider)))
199
+ {
200
+ ERR("Error allocating memory\n");
201
+ return NTE_NO_MEMORY;
202
+ }
203
+
204
+ status = BCryptGenerateKeyPair(BCRYPT_RSA_ALG_HANDLE, &object->key.bcrypt_key, default_bitlen, 0);
205
+ if (status != STATUS_SUCCESS)
206
+ {
207
+ ERR("Error generating key pair %#lx\n", status);
208
+ free(object);
209
+ return map_ntstatus(status);
210
+ }
211
+
212
+ set_object_property(object, NCRYPT_LENGTH_PROPERTY, (BYTE *)&default_bitlen, sizeof(default_bitlen));
213
+ set_object_property(object, BCRYPT_PUBLIC_KEY_LENGTH, (BYTE *)&default_bitlen, sizeof(default_bitlen));
214
+ }
215
+ else if (!lstrcmpiW(algid, BCRYPT_ECDSA_P256_ALGORITHM))
216
+ {
217
+ NTSTATUS status;
218
+ DWORD bitlen = 256;
219
+
220
+ if (!(object = create_key_object(ECDSA_P256, provider)))
221
+ return NTE_NO_MEMORY;
222
+
223
+ status = BCryptGenerateKeyPair(BCRYPT_ECDSA_P256_ALG_HANDLE, &object->key.bcrypt_key, bitlen, 0);
224
+ if (status != STATUS_SUCCESS)
225
+ {
226
+ free(object);
227
+ return map_ntstatus(status);
228
+ }
229
+
230
+ set_object_property(object, NCRYPT_LENGTH_PROPERTY, (BYTE *)&bitlen, sizeof(bitlen));
231
+ set_object_property(object, BCRYPT_PUBLIC_KEY_LENGTH, (BYTE *)&bitlen, sizeof(bitlen));
232
+ }
233
+ else
234
+ {
235
+ FIXME("Algorithm not handled %s\n", wine_dbgstr_w(algid));
236
+ return NTE_NOT_SUPPORTED;
237
+ }
238
+
239
+ *key = (NCRYPT_KEY_HANDLE)object;
240
+ return ERROR_SUCCESS;
241
+ }
242
+
243
+ SECURITY_STATUS WINAPI NCryptDecrypt(NCRYPT_KEY_HANDLE key, BYTE *input, DWORD insize, void *padding,
244
+ BYTE *output, DWORD outsize, DWORD *result, DWORD flags)
245
+ {
246
+ FIXME("(%#Ix, %p, %lu, %p, %p, %lu, %p, %#lx): stub\n", key, input, insize, padding,
247
+ output, outsize, result, flags);
248
+ return NTE_NOT_SUPPORTED;
249
+ }
250
+
251
+ SECURITY_STATUS WINAPI NCryptDeleteKey(NCRYPT_KEY_HANDLE key, DWORD flags)
252
+ {
253
+ FIXME("(%#Ix, %#lx): stub\n", key, flags);
254
+ return NTE_NOT_SUPPORTED;
255
+ }
256
+
257
+ SECURITY_STATUS WINAPI NCryptEncrypt(NCRYPT_KEY_HANDLE key, BYTE *input, DWORD insize, void *padding,
258
+ BYTE *output, DWORD outsize, DWORD *result, DWORD flags)
259
+ {
260
+ struct object *key_object = (struct object *)key;
261
+
262
+ TRACE("(%#Ix, %p, %lu, %p, %p, %lu, %p, %#lx)\n", key, input, insize, padding,
263
+ output, outsize, result, flags);
264
+
265
+ if (flags & ~(NCRYPT_NO_PADDING_FLAG | NCRYPT_PAD_OAEP_FLAG
266
+ | NCRYPT_PAD_PKCS1_FLAG | NCRYPT_SILENT_FLAG))
267
+ {
268
+ FIXME("Flags %lx not supported\n", flags);
269
+ return NTE_BAD_FLAGS;
270
+ }
271
+
272
+ if (flags & NCRYPT_NO_PADDING_FLAG || flags & NCRYPT_PAD_OAEP_FLAG)
273
+ {
274
+ FIXME("No padding and oaep padding not supported\n");
275
+ return NTE_NOT_SUPPORTED;
276
+ }
277
+
278
+ if (key_object->type != KEY) return NTE_INVALID_HANDLE;
279
+
280
+ return map_ntstatus(BCryptEncrypt(key_object->key.bcrypt_key, input, insize, padding,
281
+ NULL, 0, output, outsize, result, flags));
282
+ }
283
+
284
+ SECURITY_STATUS WINAPI NCryptEnumAlgorithms(NCRYPT_PROV_HANDLE provider, DWORD alg_ops,
285
+ DWORD *alg_count, NCryptAlgorithmName **alg_list, DWORD flags)
286
+ {
287
+ FIXME("(%#Ix, %#lx, %p, %p, %#lx): stub\n", provider, alg_ops, alg_count, alg_list, flags);
288
+ return NTE_NOT_SUPPORTED;
289
+ }
290
+
291
+ SECURITY_STATUS WINAPI NCryptEnumKeys(NCRYPT_PROV_HANDLE provider, const WCHAR *scope,
292
+ NCryptKeyName **key_name, PVOID *enum_state, DWORD flags)
293
+ {
294
+ FIXME("(%#Ix, %p, %p, %p, %#lx): stub\n", provider, scope, key_name, enum_state, flags);
295
+ return NTE_NOT_SUPPORTED;
296
+ }
297
+
298
+ SECURITY_STATUS WINAPI NCryptFinalizeKey(NCRYPT_KEY_HANDLE handle, DWORD flags)
299
+ {
300
+ struct object *object = (struct object *)handle;
301
+ DWORD key_length;
302
+ struct object_property *prop;
303
+ NTSTATUS status;
304
+
305
+ TRACE("(%#Ix, %#lx)\n", handle, flags);
306
+
307
+ if (!object || object->type != KEY) return NTE_INVALID_HANDLE;
308
+
309
+ if (!(prop = get_object_property(object, NCRYPT_LENGTH_PROPERTY))) return NTE_INVALID_HANDLE;
310
+ key_length = *(DWORD *)prop->value;
311
+ status = BCryptSetProperty(object->key.bcrypt_key, BCRYPT_KEY_LENGTH, (UCHAR *)&key_length, sizeof(key_length), 0);
312
+ if (status != STATUS_SUCCESS)
313
+ {
314
+ ERR("Error setting key length property\n");
315
+ return map_ntstatus(status);
316
+ }
317
+
318
+ status = BCryptFinalizeKeyPair(object->key.bcrypt_key, 0);
319
+ if (status != STATUS_SUCCESS)
320
+ {
321
+ ERR("Error finalizing key pair\n");
322
+ return map_ntstatus(status);
323
+ }
324
+
325
+ return ERROR_SUCCESS;
326
+ }
327
+
328
+ SECURITY_STATUS WINAPI NCryptFreeBuffer(PVOID buf)
329
+ {
330
+ FIXME("(%p): stub\n", buf);
331
+ return NTE_NOT_SUPPORTED;
332
+ }
333
+
334
+ static SECURITY_STATUS free_key_object(struct key *key)
335
+ {
336
+ return map_ntstatus( BCryptDestroyKey(key->bcrypt_key) );
337
+ }
338
+
339
+ SECURITY_STATUS WINAPI NCryptFreeObject(NCRYPT_HANDLE handle)
340
+ {
341
+ struct object *object = (struct object *)handle;
342
+ SECURITY_STATUS ret = STATUS_SUCCESS;
343
+ unsigned int i;
344
+
345
+ TRACE("(%#Ix)\n", handle);
346
+
347
+ if (!object)
348
+ {
349
+ WARN("invalid handle %#Ix\n", handle);
350
+ return NTE_INVALID_HANDLE;
351
+ }
352
+
353
+ switch (object->type)
354
+ {
355
+ case KEY:
356
+ {
357
+ if ((ret = free_key_object(&object->key))) return ret;
358
+ break;
359
+ }
360
+ case STORAGE_PROVIDER:
361
+ if (InterlockedDecrement(&object->refs))
362
+ return 0;
363
+ break;
364
+
365
+ default:
366
+ WARN("invalid handle %#Ix\n", handle);
367
+ return NTE_INVALID_HANDLE;
368
+ }
369
+
370
+ for (i = 0; i < object->num_properties; i++)
371
+ {
372
+ if (!wcscmp(object->properties[i].key, NCRYPT_PROVIDER_HANDLE_PROPERTY))
373
+ NCryptFreeObject(*(NCRYPT_HANDLE *)object->properties[i].value);
374
+
375
+ free(object->properties[i].key);
376
+ free(object->properties[i].value);
377
+ }
378
+ free(object->properties);
379
+ free(object);
380
+ return ret;
381
+ }
382
+
383
+ SECURITY_STATUS WINAPI NCryptGetProperty(NCRYPT_HANDLE handle, const WCHAR *name, BYTE *output,
384
+ DWORD outsize, DWORD *result, DWORD flags)
385
+ {
386
+ struct object *object = (struct object *)handle;
387
+ const struct object_property *property;
388
+
389
+ TRACE("(%#Ix, %s, %p, %lu, %p, %#lx)\n", handle, wine_dbgstr_w(name), output, outsize, result, flags);
390
+ if (flags) FIXME("flags %#lx not supported\n", flags);
391
+
392
+ if (!object) return NTE_INVALID_HANDLE;
393
+ if (!(property = get_object_property(object, name))) return NTE_INVALID_PARAMETER;
394
+
395
+ *result = property->value_size;
396
+ if (!output) return ERROR_SUCCESS;
397
+ if (outsize < property->value_size) return NTE_BUFFER_TOO_SMALL;
398
+
399
+ memcpy(output, property->value, property->value_size);
400
+ if (!wcscmp(name, NCRYPT_PROVIDER_HANDLE_PROPERTY))
401
+ provider_addref(*(NCRYPT_PROV_HANDLE*)property->value);
402
+ return ERROR_SUCCESS;
403
+ }
404
+
405
+ SECURITY_STATUS WINAPI NCryptImportKey(NCRYPT_PROV_HANDLE provider, NCRYPT_KEY_HANDLE decrypt_key,
406
+ const WCHAR *type, NCryptBufferDesc *params, NCRYPT_KEY_HANDLE *handle,
407
+ BYTE *data, DWORD datasize, DWORD flags)
408
+ {
409
+ BCRYPT_KEY_BLOB *header = (BCRYPT_KEY_BLOB *)data;
410
+ struct object *object;
411
+
412
+ TRACE("(%#Ix, %#Ix, %s, %p, %p, %p, %lu, %#lx)\n", provider, decrypt_key, wine_dbgstr_w(type),
413
+ params, handle, data, datasize, flags);
414
+
415
+ if (decrypt_key)
416
+ {
417
+ FIXME("Key blob decryption not implemented\n");
418
+ return NTE_NOT_SUPPORTED;
419
+ }
420
+ if (params)
421
+ {
422
+ FIXME("Parameter information not implemented\n");
423
+ return NTE_NOT_SUPPORTED;
424
+ }
425
+ if (flags == NCRYPT_SILENT_FLAG)
426
+ {
427
+ FIXME("Silent flag not implemented\n");
428
+ }
429
+ else if (flags)
430
+ {
431
+ WARN("Invalid flags %#lx\n", flags);
432
+ return NTE_BAD_FLAGS;
433
+ }
434
+ if (!header) return NTE_INVALID_PARAMETER;
435
+
436
+ switch (header->Magic)
437
+ {
438
+ case BCRYPT_RSAFULLPRIVATE_MAGIC:
439
+ case BCRYPT_RSAPRIVATE_MAGIC:
440
+ case BCRYPT_RSAPUBLIC_MAGIC:
441
+ {
442
+ NTSTATUS status;
443
+ BCRYPT_RSAKEY_BLOB *rsablob = (BCRYPT_RSAKEY_BLOB *)data;
444
+
445
+ if (!(object = create_key_object(RSA, provider)))
446
+ {
447
+ ERR("Error allocating memory\n");
448
+ return NTE_NO_MEMORY;
449
+ }
450
+
451
+ status = BCryptImportKeyPair(BCRYPT_RSA_ALG_HANDLE, NULL, type, &object->key.bcrypt_key, data, datasize, 0);
452
+ if (status != STATUS_SUCCESS)
453
+ {
454
+ WARN("Error importing key pair %#lx\n", status);
455
+ free(object);
456
+ return map_ntstatus(status);
457
+ }
458
+
459
+ set_object_property(object, NCRYPT_LENGTH_PROPERTY, (BYTE *)&rsablob->BitLength, sizeof(rsablob->BitLength));
460
+ set_object_property(object, BCRYPT_PUBLIC_KEY_LENGTH, (BYTE *)&rsablob->BitLength, sizeof(rsablob->BitLength));
461
+ break;
462
+ }
463
+ default:
464
+ FIXME("Unhandled key magic %#lx\n", header->Magic);
465
+ return NTE_INVALID_PARAMETER;
466
+ }
467
+
468
+ *handle = (NCRYPT_KEY_HANDLE)object;
469
+ return ERROR_SUCCESS;
470
+ }
471
+
472
+ SECURITY_STATUS WINAPI NCryptExportKey(NCRYPT_KEY_HANDLE key, NCRYPT_KEY_HANDLE encrypt_key, const WCHAR *type,
473
+ NCryptBufferDesc *params, BYTE *output, DWORD output_len, DWORD *ret_len,
474
+ DWORD flags)
475
+ {
476
+ struct object *object = (struct object *)key;
477
+
478
+ TRACE("(%#Ix, %#Ix, %s, %p, %p, %lu, %p, %#lx)\n", key, encrypt_key, wine_dbgstr_w(type), params, output,
479
+ output_len, ret_len, flags);
480
+
481
+ if (encrypt_key)
482
+ {
483
+ FIXME("Key blob encryption not implemented\n");
484
+ return NTE_NOT_SUPPORTED;
485
+ }
486
+ if (params)
487
+ {
488
+ FIXME("Parameter information not implemented\n");
489
+ return NTE_NOT_SUPPORTED;
490
+ }
491
+ if (flags == NCRYPT_SILENT_FLAG)
492
+ {
493
+ FIXME("Silent flag not implemented\n");
494
+ }
495
+
496
+ return map_ntstatus(BCryptExportKey(object->key.bcrypt_key, NULL, type, output, output_len, ret_len, 0));
497
+ }
498
+
499
+ SECURITY_STATUS WINAPI NCryptIsAlgSupported(NCRYPT_PROV_HANDLE provider, const WCHAR *algid, DWORD flags)
500
+ {
501
+ static const ULONG supported = BCRYPT_CIPHER_OPERATION |\
502
+ BCRYPT_ASYMMETRIC_ENCRYPTION_OPERATION |\
503
+ BCRYPT_SIGNATURE_OPERATION |\
504
+ BCRYPT_SECRET_AGREEMENT_OPERATION;
505
+ BCRYPT_ALGORITHM_IDENTIFIER *list;
506
+ ULONG i, count;
507
+ NTSTATUS status;
508
+
509
+ TRACE("(%#Ix, %s, %#lx)\n", provider, wine_dbgstr_w(algid), flags);
510
+
511
+ if (!provider) return NTE_INVALID_HANDLE;
512
+ if (!algid) return HRESULT_FROM_WIN32(RPC_X_NULL_REF_POINTER);
513
+ if (flags == NCRYPT_SILENT_FLAG)
514
+ {
515
+ FIXME("Silent flag not implemented\n");
516
+ }
517
+ else if (flags)
518
+ {
519
+ WARN("Invalid flags %#lx\n", flags);
520
+ return NTE_BAD_FLAGS;
521
+ }
522
+ if (!lstrcmpiW(BCRYPT_RSA_SIGN_ALGORITHM, algid)) return NTE_NOT_SUPPORTED;
523
+
524
+ status = BCryptEnumAlgorithms(supported, &count, &list, 0);
525
+ if (status != STATUS_SUCCESS)
526
+ {
527
+ ERR("Error retrieving algorithm list %#lx\n", status);
528
+ return map_ntstatus(status);
529
+ }
530
+
531
+ status = STATUS_NOT_SUPPORTED;
532
+ for (i = 0; i < count; i++)
533
+ {
534
+ if (!lstrcmpiW(list[i].pszName, algid))
535
+ {
536
+ status = STATUS_SUCCESS;
537
+ break;
538
+ }
539
+ }
540
+
541
+ BCryptFreeBuffer(list);
542
+ return map_ntstatus(status);
543
+ }
544
+
545
+ BOOL WINAPI NCryptIsKeyHandle(NCRYPT_KEY_HANDLE hKey)
546
+ {
547
+ FIXME("(%#Ix): stub\n", hKey);
548
+ return FALSE;
549
+ }
550
+
551
+ SECURITY_STATUS WINAPI NCryptOpenKey(NCRYPT_PROV_HANDLE provider, NCRYPT_KEY_HANDLE *key,
552
+ const WCHAR *name, DWORD keyspec, DWORD flags)
553
+ {
554
+ FIXME("(%#Ix, %p, %s, %#lx, %#lx): stub\n", provider, key, wine_dbgstr_w(name), keyspec, flags);
555
+ return NTE_NOT_SUPPORTED;
556
+ }
557
+
558
+ SECURITY_STATUS WINAPI NCryptOpenStorageProvider(NCRYPT_PROV_HANDLE *provider, const WCHAR *name, DWORD flags)
559
+ {
560
+ struct object *object;
561
+
562
+ FIXME("(%p, %s, %#lx): stub\n", provider, wine_dbgstr_w(name), flags);
563
+
564
+ if (!(object = allocate_object(STORAGE_PROVIDER)))
565
+ {
566
+ ERR("Error allocating memory.\n");
567
+ return NTE_NO_MEMORY;
568
+ }
569
+ *provider = (NCRYPT_PROV_HANDLE)object;
570
+ return ERROR_SUCCESS;
571
+ }
572
+
573
+ SECURITY_STATUS WINAPI NCryptSetProperty(NCRYPT_HANDLE handle, const WCHAR *name, BYTE *input, DWORD insize, DWORD flags)
574
+ {
575
+ struct object *object = (struct object *)handle;
576
+
577
+ TRACE("(%#Ix, %s, %p, %lu, %#lx)\n", handle, wine_dbgstr_w(name), input, insize, flags);
578
+ if (flags) FIXME("flags %#lx not supported\n", flags);
579
+
580
+ if (!object) return NTE_INVALID_HANDLE;
581
+ if (!wcscmp(name, NCRYPT_PROVIDER_HANDLE_PROPERTY)) return NTE_NOT_SUPPORTED;
582
+ return set_object_property(object, name, input, insize);
583
+ }
584
+
585
+ SECURITY_STATUS WINAPI NCryptSignHash(NCRYPT_KEY_HANDLE handle, void *padding, BYTE *value, DWORD value_len,
586
+ BYTE *sig, DWORD sig_len, DWORD *ret_len, DWORD flags)
587
+ {
588
+ struct object *object = (struct object *)handle;
589
+
590
+ TRACE("(%#Ix, %p, %p, %lu, %p, %lu, %#lx)\n", handle, padding, value, value_len, sig, sig_len, flags);
591
+ if (flags & NCRYPT_SILENT_FLAG) FIXME("Silent flag not implemented\n");
592
+
593
+ if (!object || object->type != KEY) return NTE_INVALID_HANDLE;
594
+
595
+ return map_ntstatus(BCryptSignHash(object->key.bcrypt_key, padding, value, value_len, sig, sig_len,
596
+ ret_len, flags & ~NCRYPT_SILENT_FLAG));
597
+ }
598
+
599
+ SECURITY_STATUS WINAPI NCryptVerifySignature(NCRYPT_KEY_HANDLE handle, void *padding, BYTE *hash, DWORD hash_size,
600
+ BYTE *signature, DWORD signature_size, DWORD flags)
601
+ {
602
+ struct object *key_object = (struct object *)handle;
603
+
604
+ TRACE("(%#Ix, %p, %p, %lu, %p, %lu, %#lx)\n", handle, padding, hash, hash_size, signature,
605
+ signature_size, flags);
606
+
607
+ if (!hash_size || !signature_size) return NTE_INVALID_PARAMETER;
608
+ if (!hash || !signature) return HRESULT_FROM_WIN32(RPC_X_NULL_REF_POINTER);
609
+ if (!handle || key_object->type != KEY) return NTE_INVALID_HANDLE;
610
+
611
+ if (key_object->key.algid < RSA)
612
+ {
613
+ FIXME("Symmetric keys not supported.\n");
614
+ return NTE_NOT_SUPPORTED;
615
+ }
616
+
617
+ return map_ntstatus(BCryptVerifySignature(key_object->key.bcrypt_key, padding, hash, hash_size, signature,
618
+ signature_size, flags));
619
+ }
@@ -0,0 +1,11 @@
1
+ --- a/dlls/ncrypt/main.c
2
+ +++ b/dlls/ncrypt/main.c
3
+ @@ -269,7 +269,7 @@
4
+ return NTE_BAD_FLAGS;
5
+ }
6
+
7
+ - if (flags & NCRYPT_NO_PADDING_FLAG || flags & NCRYPT_PAD_OAEP_FLAG)
8
+ + if (flags & NCRYPT_NO_PADDING_FLAG)
9
+ {
10
+ FIXME("No padding and oaep padding not supported\n");
11
+ return NTE_NOT_SUPPORTED;
@@ -0,0 +1,22 @@
1
+ # Wine signal-state adapter
2
+
3
+ Wine 11.19 can clear AVX presence during SIGUSR1 suspend/resume when the returned YMM-high registers are zero. Rosetta's Linux signal return requires all three advertised x87/SSE/AVX components to remain present. A native reproducer returns exit 133 with the same `ThreadContextSignals.cpp:414` assertion; an explicit zero AVX component returns successfully. Ten actual Frame cold builds passed with this adapter after the fresh image and the NGen-drained control reproduced the fault.
4
+
5
+ The adapter wraps Wine's single `SA_SIGINFO` SIGUSR1 handler. For the validated Linux layout (magic words, 832-byte state, 836-byte extended area and layout features 7), it changes only entry features 7 → returned features 3: zero the 256 YMM-high bytes and mark AVX present. Absent AVX already means that same zero architectural state. Legacy registers, existing nonzero AVX, other transitions and reserved fields remain untouched. The returned frame pointer is revalidated.
6
+
7
+ The original handler is bound immutably before registration, so concurrent disposition changes cannot redirect an active wrapper. Other handlers are delegated; masks, flags, queries, default and ignore are preserved. This is scoped to Wine's successful registration after loader initialization: the shipped Wine executables depend only on libc and register with `old_action = NULL`, aborting on failure. It is not a generic preload for arbitrary dependency constructors.
8
+
9
+ The launcher sets `LD_PRELOAD` only while executing Wine. Ubuntu's `$LIB` expansion selects the AMD64 adapter or an empty i386 library, including child processes. Setup under FEX does not use this launcher. Vendor binaries and their status/result checks are unchanged.
10
+
11
+ ## Native checks
12
+
13
+ Run `check.sh` inside AMD64 Ubuntu Linux with GCC, libc development headers, Python, the i386 loader and AVX support. The Docker recipe's `wine-signal-compat` stage has these tools. The fixtures check 23 frame/handler cases, real signal return, zero/nonzero AVX register preservation, and both actual loader-expanded paths without warnings. No generated binaries are maintained. The command prints its temporary artifact directory and retains failure logs; a disposable container owns cleanup.
14
+
15
+ ```sh
16
+ docker build --platform linux/amd64 --target wine-signal-compat \
17
+ -f packages/build/docker/Dockerfile -t tsplc-wine-signal-check packages/build
18
+ docker run --rm --platform linux/amd64 --entrypoint /bin/sh \
19
+ tsplc-wine-signal-check /opt/codesys-install/wine-signal/check.sh
20
+ ```
21
+
22
+ The exact ABI and Wine mechanism are documented in the primary [Linux signal ABI](https://github.com/torvalds/linux/blob/v6.17/arch/x86/include/uapi/asm/sigcontext.h), [Linux signal restore](https://github.com/torvalds/linux/blob/v6.17/arch/x86/kernel/fpu/signal.c), and [Wine 11.19 suspend/resume state conversion](https://github.com/wine-mirror/wine/blob/wine-11.19/dlls/ntdll/unix/thread.c). The completed-log native assertion guard still rejects any remaining helper fault, even if the main launcher reports zero.
@@ -0,0 +1,10 @@
1
+ #!/bin/sh
2
+ set -eu
3
+ sources=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
4
+ output=${1:?Usage: build.sh OUTPUT_DIRECTORY}
5
+ mkdir -p "$output/lib/x86_64-linux-gnu" "$output/lib/i386-linux-gnu"
6
+ gcc -shared -fPIC -Wall -Wextra -Werror -O2 -fno-tree-vectorize \
7
+ "$sources/signal-state.c" -ldl -o "$output/lib/x86_64-linux-gnu/signal-state.so"
8
+ # No 32-bit libc or headers are needed for this empty shared object.
9
+ gcc -m32 -shared -fPIC -nostdlib -Wall -Wextra -Werror -O2 \
10
+ "$sources/noop-i386.c" -o "$output/lib/i386-linux-gnu/signal-state.so"