Coverage Report

Created: 2026-06-15 06:52

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/FreeRDP/winpr/libwinpr/sspi/Schannel/schannel.c
Line
Count
Source
1
/**
2
 * WinPR: Windows Portable Runtime
3
 * Schannel Security Package
4
 *
5
 * Copyright 2012-2014 Marc-Andre Moreau <marcandre.moreau@gmail.com>
6
 *
7
 * Licensed under the Apache License, Version 2.0 (the "License");
8
 * you may not use this file except in compliance with the License.
9
 * You may obtain a copy of the License at
10
 *
11
 *     http://www.apache.org/licenses/LICENSE-2.0
12
 *
13
 * Unless required by applicable law or agreed to in writing, software
14
 * distributed under the License is distributed on an "AS IS" BASIS,
15
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
 * See the License for the specific language governing permissions and
17
 * limitations under the License.
18
 */
19
20
#include <winpr/config.h>
21
22
#include <winpr/crt.h>
23
#include <winpr/sspi.h>
24
25
#include "schannel.h"
26
27
#include "../sspi.h"
28
#include "../../log.h"
29
30
static char SCHANNEL_PACKAGE_NAME_A[] = "Schannel";
31
static WCHAR SCHANNEL_PACKAGE_NAME_W[] = { W('S'), W('c'), W('h'), W('a'), W('n'),
32
                                         W('n'), W('e'), W('l'), W('\0') };
33
34
#define TAG WINPR_TAG("sspi.Schannel")
35
36
SCHANNEL_CONTEXT* schannel_ContextNew(void)
37
0
{
38
0
  SCHANNEL_CONTEXT* context = nullptr;
39
0
  context = (SCHANNEL_CONTEXT*)calloc(1, sizeof(SCHANNEL_CONTEXT));
40
41
0
  if (!context)
42
0
    return nullptr;
43
44
0
  context->openssl = schannel_openssl_new();
45
46
0
  if (!context->openssl)
47
0
  {
48
0
    free(context);
49
0
    return nullptr;
50
0
  }
51
52
0
  return context;
53
0
}
54
55
void schannel_ContextFree(SCHANNEL_CONTEXT* context)
56
0
{
57
0
  if (!context)
58
0
    return;
59
60
0
  schannel_openssl_free(context->openssl);
61
0
  free(context);
62
0
}
63
64
static SCHANNEL_CREDENTIALS* schannel_CredentialsNew(void)
65
0
{
66
0
  SCHANNEL_CREDENTIALS* credentials = nullptr;
67
0
  credentials = (SCHANNEL_CREDENTIALS*)calloc(1, sizeof(SCHANNEL_CREDENTIALS));
68
0
  return credentials;
69
0
}
70
71
static void schannel_CredentialsFree(SCHANNEL_CREDENTIALS* credentials)
72
0
{
73
0
  free(credentials);
74
0
}
75
76
static ALG_ID schannel_SupportedAlgs[] = { CALG_AES_128,
77
                                         CALG_AES_256,
78
                                         CALG_RC4,
79
                                         CALG_DES,
80
                                         CALG_3DES,
81
                                         CALG_MD5,
82
                                         CALG_SHA1,
83
                                         CALG_SHA_256,
84
                                         CALG_SHA_384,
85
                                         CALG_SHA_512,
86
                                         CALG_RSA_SIGN,
87
                                         CALG_DH_EPHEM,
88
                                         (ALG_CLASS_KEY_EXCHANGE | ALG_TYPE_RESERVED7 |
89
                                          6), /* what is this? */
90
                                         CALG_DSS_SIGN,
91
                                         CALG_ECDSA };
92
93
static SECURITY_STATUS SEC_ENTRY schannel_QueryCredentialsAttributesW(
94
    WINPR_ATTR_UNUSED PCredHandle phCredential, ULONG ulAttribute, void* pBuffer)
95
0
{
96
0
  if (ulAttribute == SECPKG_ATTR_SUPPORTED_ALGS)
97
0
  {
98
0
    PSecPkgCred_SupportedAlgs SupportedAlgs = (PSecPkgCred_SupportedAlgs)pBuffer;
99
0
    SupportedAlgs->cSupportedAlgs = sizeof(schannel_SupportedAlgs) / sizeof(ALG_ID);
100
0
    SupportedAlgs->palgSupportedAlgs = (ALG_ID*)schannel_SupportedAlgs;
101
0
    return SEC_E_OK;
102
0
  }
103
0
  else if (ulAttribute == SECPKG_ATTR_CIPHER_STRENGTHS)
104
0
  {
105
0
    PSecPkgCred_CipherStrengths CipherStrengths = (PSecPkgCred_CipherStrengths)pBuffer;
106
0
    CipherStrengths->dwMinimumCipherStrength = 40;
107
0
    CipherStrengths->dwMaximumCipherStrength = 256;
108
0
    return SEC_E_OK;
109
0
  }
110
0
  else if (ulAttribute == SECPKG_ATTR_SUPPORTED_PROTOCOLS)
111
0
  {
112
0
    PSecPkgCred_SupportedProtocols SupportedProtocols = (PSecPkgCred_SupportedProtocols)pBuffer;
113
    /* Observed SupportedProtocols: 0x208A0 */
114
0
    SupportedProtocols->grbitProtocol = (SP_PROT_CLIENTS | SP_PROT_SERVERS);
115
0
    return SEC_E_OK;
116
0
  }
117
118
0
  WLog_ERR(TAG, "TODO: Implement ulAttribute=%08" PRIx32, ulAttribute);
119
0
  return SEC_E_UNSUPPORTED_FUNCTION;
120
0
}
121
122
static SECURITY_STATUS SEC_ENTRY schannel_QueryCredentialsAttributesA(PCredHandle phCredential,
123
                                                                      ULONG ulAttribute,
124
                                                                      void* pBuffer)
125
0
{
126
0
  return schannel_QueryCredentialsAttributesW(phCredential, ulAttribute, pBuffer);
127
0
}
128
129
static SECURITY_STATUS SEC_ENTRY schannel_AcquireCredentialsHandleX(
130
    void* name, ULONG fCredentialUse, WINPR_ATTR_UNUSED void* pvLogonID, void* pAuthData,
131
    WINPR_ATTR_UNUSED SEC_GET_KEY_FN pGetKeyFn, WINPR_ATTR_UNUSED void* pvGetKeyArgument,
132
    PCredHandle phCredential, WINPR_ATTR_UNUSED PTimeStamp ptsExpiry)
133
0
{
134
0
  WINPR_ASSERT(name);
135
136
0
  if (fCredentialUse == SECPKG_CRED_OUTBOUND)
137
0
  {
138
0
    SCHANNEL_CREDENTIALS* credentials = schannel_CredentialsNew();
139
0
    if (!credentials)
140
0
      return SEC_E_INSUFFICIENT_MEMORY;
141
142
0
    credentials->fCredentialUse = fCredentialUse;
143
0
    SCHANNEL_CRED* cred = (SCHANNEL_CRED*)pAuthData;
144
145
0
    if (cred)
146
0
      CopyMemory(&credentials->cred, cred, sizeof(SCHANNEL_CRED));
147
148
0
    sspi_SecureHandleSetLowerPointer(phCredential, (void*)credentials);
149
0
    sspi_SecureHandleSetUpperPointer(phCredential, name);
150
0
    return SEC_E_OK;
151
0
  }
152
0
  else if (fCredentialUse == SECPKG_CRED_INBOUND)
153
0
  {
154
0
    SCHANNEL_CREDENTIALS* credentials = schannel_CredentialsNew();
155
0
    if (!credentials)
156
0
      return SEC_E_INSUFFICIENT_MEMORY;
157
158
0
    credentials->fCredentialUse = fCredentialUse;
159
0
    sspi_SecureHandleSetLowerPointer(phCredential, (void*)credentials);
160
0
    sspi_SecureHandleSetUpperPointer(phCredential, name);
161
0
    return SEC_E_OK;
162
0
  }
163
0
  else
164
0
    WLog_WARN(TAG, "Unsupported fCredentialUse=0x%08" PRIx32, fCredentialUse);
165
166
0
  return SEC_E_OK;
167
0
}
168
169
// NOLINTBEGIN(readability-non-const-parameter)
170
static SECURITY_STATUS SEC_ENTRY schannel_AcquireCredentialsHandleA(
171
    SEC_CHAR* pszPrincipal, SEC_CHAR* pszPackage, ULONG fCredentialUse, void* pvLogonID,
172
    void* pAuthData, SEC_GET_KEY_FN pGetKeyFn, void* pvGetKeyArgument, PCredHandle phCredential,
173
    PTimeStamp ptsExpiry)
174
0
{
175
0
  WINPR_UNUSED(pszPrincipal);
176
0
  WINPR_UNUSED(pszPackage);
177
0
  return schannel_AcquireCredentialsHandleX(SCHANNEL_PACKAGE_NAME_A, fCredentialUse, pvLogonID,
178
0
                                            pAuthData, pGetKeyFn, pvGetKeyArgument, phCredential,
179
0
                                            ptsExpiry);
180
0
}
181
182
static SECURITY_STATUS SEC_ENTRY schannel_AcquireCredentialsHandleW(
183
    WINPR_ATTR_UNUSED SEC_WCHAR* pszPrincipal, WINPR_ATTR_UNUSED SEC_WCHAR* pszPackage,
184
    ULONG fCredentialUse, WINPR_ATTR_UNUSED void* pvLogonID, void* pAuthData,
185
    WINPR_ATTR_UNUSED SEC_GET_KEY_FN pGetKeyFn, WINPR_ATTR_UNUSED void* pvGetKeyArgument,
186
    PCredHandle phCredential, WINPR_ATTR_UNUSED PTimeStamp ptsExpiry)
187
// NOLINTEND(readability-non-const-parameter)
188
0
{
189
0
  WINPR_UNUSED(pszPrincipal);
190
0
  WINPR_UNUSED(pszPackage);
191
0
  return schannel_AcquireCredentialsHandleX(SCHANNEL_PACKAGE_NAME_W, fCredentialUse, pvLogonID,
192
0
                                            pAuthData, pGetKeyFn, pvGetKeyArgument, phCredential,
193
0
                                            ptsExpiry);
194
0
}
195
196
static SECURITY_STATUS SEC_ENTRY schannel_FreeCredentialsHandle(PCredHandle phCredential)
197
0
{
198
0
  if (!phCredential)
199
0
    return SEC_E_INVALID_HANDLE;
200
201
0
  SCHANNEL_CREDENTIALS* credentials =
202
0
      (SCHANNEL_CREDENTIALS*)sspi_SecureHandleGetLowerPointer(phCredential);
203
0
  sspi_SecureHandleInvalidate(phCredential);
204
0
  if (!credentials)
205
0
    return SEC_E_INVALID_HANDLE;
206
207
0
  schannel_CredentialsFree(credentials);
208
0
  return SEC_E_OK;
209
0
}
210
211
static SECURITY_STATUS SEC_ENTRY schannel_InitializeSecurityContextX(
212
    void* name, PCredHandle phCredential, PCtxtHandle phContext,
213
    WINPR_ATTR_UNUSED SEC_WCHAR* pszTargetName, WINPR_ATTR_UNUSED ULONG fContextReq,
214
    WINPR_ATTR_UNUSED ULONG Reserved1, WINPR_ATTR_UNUSED ULONG TargetDataRep, PSecBufferDesc pInput,
215
    WINPR_ATTR_UNUSED ULONG Reserved2, PCtxtHandle phNewContext, PSecBufferDesc pOutput,
216
    WINPR_ATTR_UNUSED PULONG pfContextAttr, WINPR_ATTR_UNUSED PTimeStamp ptsExpiry)
217
0
{
218
0
  SECURITY_STATUS status = 0;
219
0
  SCHANNEL_CONTEXT* context = nullptr;
220
0
  SCHANNEL_CREDENTIALS* credentials = nullptr;
221
222
  /* behave like windows SSPIs that don't want empty context */
223
0
  if (phContext && !phContext->dwLower && !phContext->dwUpper)
224
0
    return SEC_E_INVALID_HANDLE;
225
226
0
  context = sspi_SecureHandleGetLowerPointer(phContext);
227
228
0
  if (!context)
229
0
  {
230
0
    context = schannel_ContextNew();
231
232
0
    if (!context)
233
0
      return SEC_E_INSUFFICIENT_MEMORY;
234
235
0
    credentials = (SCHANNEL_CREDENTIALS*)sspi_SecureHandleGetLowerPointer(phCredential);
236
0
    context->server = FALSE;
237
0
    CopyMemory(&context->cred, &credentials->cred, sizeof(SCHANNEL_CRED));
238
0
    sspi_SecureHandleSetLowerPointer(phNewContext, context);
239
0
    sspi_SecureHandleSetUpperPointer(phNewContext, name);
240
0
    schannel_openssl_client_init(context->openssl);
241
0
  }
242
243
0
  status = schannel_openssl_client_process_tokens(context->openssl, pInput, pOutput);
244
0
  return status;
245
0
}
246
247
static SECURITY_STATUS SEC_ENTRY schannel_InitializeSecurityContextW(
248
    PCredHandle phCredential, PCtxtHandle phContext, SEC_WCHAR* pszTargetName, ULONG fContextReq,
249
    ULONG Reserved1, ULONG TargetDataRep, PSecBufferDesc pInput, ULONG Reserved2,
250
    PCtxtHandle phNewContext, PSecBufferDesc pOutput, PULONG pfContextAttr, PTimeStamp ptsExpiry)
251
0
{
252
0
  return schannel_InitializeSecurityContextX(
253
0
      SCHANNEL_PACKAGE_NAME_W, phCredential, phContext, pszTargetName, fContextReq, Reserved1,
254
0
      TargetDataRep, pInput, Reserved2, phNewContext, pOutput, pfContextAttr, ptsExpiry);
255
0
}
256
257
static SECURITY_STATUS SEC_ENTRY schannel_InitializeSecurityContextA(
258
    PCredHandle phCredential, PCtxtHandle phContext, SEC_CHAR* pszTargetName, ULONG fContextReq,
259
    ULONG Reserved1, ULONG TargetDataRep, PSecBufferDesc pInput, ULONG Reserved2,
260
    PCtxtHandle phNewContext, PSecBufferDesc pOutput, PULONG pfContextAttr, PTimeStamp ptsExpiry)
261
0
{
262
0
  SECURITY_STATUS status = 0;
263
0
  SEC_WCHAR* pszTargetNameW = nullptr;
264
265
0
  if (pszTargetName != nullptr)
266
0
  {
267
0
    pszTargetNameW = ConvertUtf8ToWCharAlloc(pszTargetName, nullptr);
268
0
    if (!pszTargetNameW)
269
0
      return SEC_E_INSUFFICIENT_MEMORY;
270
0
  }
271
272
0
  status = schannel_InitializeSecurityContextX(
273
0
      SCHANNEL_PACKAGE_NAME_A, phCredential, phContext, pszTargetNameW, fContextReq, Reserved1,
274
0
      TargetDataRep, pInput, Reserved2, phNewContext, pOutput, pfContextAttr, ptsExpiry);
275
0
  free(pszTargetNameW);
276
0
  return status;
277
0
}
278
279
static SECURITY_STATUS SEC_ENTRY schannel_AcceptSecurityContextA(
280
    WINPR_ATTR_UNUSED PCredHandle phCredential, PCtxtHandle phContext, PSecBufferDesc pInput,
281
    WINPR_ATTR_UNUSED ULONG fContextReq, WINPR_ATTR_UNUSED ULONG TargetDataRep,
282
    PCtxtHandle phNewContext, PSecBufferDesc pOutput, WINPR_ATTR_UNUSED PULONG pfContextAttr,
283
    WINPR_ATTR_UNUSED PTimeStamp ptsTimeStamp)
284
0
{
285
0
  SECURITY_STATUS status = 0;
286
0
  SCHANNEL_CONTEXT* context = nullptr;
287
288
  /* behave like windows SSPIs that don't want empty context */
289
0
  if (phContext && !phContext->dwLower && !phContext->dwUpper)
290
0
    return SEC_E_INVALID_HANDLE;
291
292
0
  context = (SCHANNEL_CONTEXT*)sspi_SecureHandleGetLowerPointer(phContext);
293
294
0
  if (!context)
295
0
  {
296
0
    context = schannel_ContextNew();
297
298
0
    if (!context)
299
0
      return SEC_E_INSUFFICIENT_MEMORY;
300
301
0
    context->server = TRUE;
302
0
    sspi_SecureHandleSetLowerPointer(phNewContext, context);
303
0
    sspi_SecureHandleSetUpperPointer(phNewContext, (void*)SCHANNEL_PACKAGE_NAME_A);
304
0
    schannel_openssl_server_init(context->openssl);
305
0
  }
306
307
0
  status = schannel_openssl_server_process_tokens(context->openssl, pInput, pOutput);
308
0
  return status;
309
0
}
310
311
static SECURITY_STATUS SEC_ENTRY schannel_AcceptSecurityContextW(
312
    WINPR_ATTR_UNUSED PCredHandle phCredential, PCtxtHandle phContext, PSecBufferDesc pInput,
313
    WINPR_ATTR_UNUSED ULONG fContextReq, WINPR_ATTR_UNUSED ULONG TargetDataRep,
314
    PCtxtHandle phNewContext, PSecBufferDesc pOutput, WINPR_ATTR_UNUSED PULONG pfContextAttr,
315
    WINPR_ATTR_UNUSED PTimeStamp ptsTimeStamp)
316
0
{
317
0
  SECURITY_STATUS status = 0;
318
0
  SCHANNEL_CONTEXT* context = nullptr;
319
320
  /* behave like windows SSPIs that don't want empty context */
321
0
  if (phContext && !phContext->dwLower && !phContext->dwUpper)
322
0
    return SEC_E_INVALID_HANDLE;
323
324
0
  context = (SCHANNEL_CONTEXT*)sspi_SecureHandleGetLowerPointer(phContext);
325
326
0
  if (!context)
327
0
  {
328
0
    context = schannel_ContextNew();
329
330
0
    if (!context)
331
0
      return SEC_E_INSUFFICIENT_MEMORY;
332
333
0
    context->server = TRUE;
334
0
    sspi_SecureHandleSetLowerPointer(phNewContext, context);
335
0
    sspi_SecureHandleSetUpperPointer(phNewContext, (void*)SCHANNEL_PACKAGE_NAME_W);
336
0
    schannel_openssl_server_init(context->openssl);
337
0
  }
338
339
0
  status = schannel_openssl_server_process_tokens(context->openssl, pInput, pOutput);
340
0
  return status;
341
0
}
342
343
static SECURITY_STATUS SEC_ENTRY schannel_DeleteSecurityContext(PCtxtHandle phContext)
344
0
{
345
0
  SCHANNEL_CONTEXT* context = (SCHANNEL_CONTEXT*)sspi_SecureHandleGetLowerPointer(phContext);
346
0
  sspi_SecureHandleInvalidate(phContext);
347
348
0
  if (!context)
349
0
    return SEC_E_INVALID_HANDLE;
350
351
0
  schannel_ContextFree(context);
352
0
  return SEC_E_OK;
353
0
}
354
355
static SECURITY_STATUS SEC_ENTRY schannel_QueryContextAttributes(PCtxtHandle phContext,
356
                                                                 ULONG ulAttribute, void* pBuffer)
357
0
{
358
0
  if (!phContext)
359
0
    return SEC_E_INVALID_HANDLE;
360
361
0
  if (!pBuffer)
362
0
    return SEC_E_INSUFFICIENT_MEMORY;
363
364
0
  if (ulAttribute == SECPKG_ATTR_SIZES)
365
0
  {
366
0
    SecPkgContext_Sizes* Sizes = (SecPkgContext_Sizes*)pBuffer;
367
0
    Sizes->cbMaxToken = 0x6000;
368
0
    Sizes->cbMaxSignature = 16;
369
0
    Sizes->cbBlockSize = 0;
370
0
    Sizes->cbSecurityTrailer = 16;
371
0
    return SEC_E_OK;
372
0
  }
373
0
  else if (ulAttribute == SECPKG_ATTR_STREAM_SIZES)
374
0
  {
375
0
    SecPkgContext_StreamSizes* StreamSizes = (SecPkgContext_StreamSizes*)pBuffer;
376
0
    StreamSizes->cbHeader = 5;
377
0
    StreamSizes->cbTrailer = 36;
378
0
    StreamSizes->cbMaximumMessage = 0x4000;
379
0
    StreamSizes->cBuffers = 4;
380
0
    StreamSizes->cbBlockSize = 16;
381
0
    return SEC_E_OK;
382
0
  }
383
384
0
  WLog_ERR(TAG, "TODO: Implement ulAttribute=%08" PRIx32, ulAttribute);
385
0
  return SEC_E_UNSUPPORTED_FUNCTION;
386
0
}
387
388
static SECURITY_STATUS SEC_ENTRY schannel_MakeSignature(WINPR_ATTR_UNUSED PCtxtHandle phContext,
389
                                                        WINPR_ATTR_UNUSED ULONG fQOP,
390
                                                        WINPR_ATTR_UNUSED PSecBufferDesc pMessage,
391
                                                        WINPR_ATTR_UNUSED ULONG MessageSeqNo)
392
0
{
393
0
  return SEC_E_OK;
394
0
}
395
396
static SECURITY_STATUS SEC_ENTRY schannel_VerifySignature(WINPR_ATTR_UNUSED PCtxtHandle phContext,
397
                                                          WINPR_ATTR_UNUSED PSecBufferDesc pMessage,
398
                                                          WINPR_ATTR_UNUSED ULONG MessageSeqNo,
399
                                                          WINPR_ATTR_UNUSED ULONG* pfQOP)
400
0
{
401
0
  return SEC_E_OK;
402
0
}
403
404
static SECURITY_STATUS SEC_ENTRY schannel_EncryptMessage(WINPR_ATTR_UNUSED PCtxtHandle phContext,
405
                                                         WINPR_ATTR_UNUSED ULONG fQOP,
406
                                                         PSecBufferDesc pMessage,
407
                                                         WINPR_ATTR_UNUSED ULONG MessageSeqNo)
408
0
{
409
0
  SECURITY_STATUS status = 0;
410
0
  SCHANNEL_CONTEXT* context = nullptr;
411
0
  context = (SCHANNEL_CONTEXT*)sspi_SecureHandleGetLowerPointer(phContext);
412
413
0
  if (!context)
414
0
    return SEC_E_INVALID_HANDLE;
415
416
0
  status = schannel_openssl_encrypt_message(context->openssl, pMessage);
417
0
  return status;
418
0
}
419
420
static SECURITY_STATUS SEC_ENTRY schannel_DecryptMessage(PCtxtHandle phContext,
421
                                                         PSecBufferDesc pMessage,
422
                                                         WINPR_ATTR_UNUSED ULONG MessageSeqNo,
423
                                                         WINPR_ATTR_UNUSED ULONG* pfQOP)
424
0
{
425
0
  SECURITY_STATUS status = 0;
426
0
  SCHANNEL_CONTEXT* context = nullptr;
427
0
  context = (SCHANNEL_CONTEXT*)sspi_SecureHandleGetLowerPointer(phContext);
428
429
0
  if (!context)
430
0
    return SEC_E_INVALID_HANDLE;
431
432
0
  status = schannel_openssl_decrypt_message(context->openssl, pMessage);
433
0
  return status;
434
0
}
435
436
const SecurityFunctionTableA SCHANNEL_SecurityFunctionTableA = {
437
  3,                                    /* dwVersion */
438
  nullptr,                              /* EnumerateSecurityPackages */
439
  schannel_QueryCredentialsAttributesA, /* QueryCredentialsAttributes */
440
  schannel_AcquireCredentialsHandleA,   /* AcquireCredentialsHandle */
441
  schannel_FreeCredentialsHandle,       /* FreeCredentialsHandle */
442
  nullptr,                              /* Reserved2 */
443
  schannel_InitializeSecurityContextA,  /* InitializeSecurityContext */
444
  schannel_AcceptSecurityContextA,      /* AcceptSecurityContext */
445
  nullptr,                              /* CompleteAuthToken */
446
  schannel_DeleteSecurityContext,       /* DeleteSecurityContext */
447
  nullptr,                              /* ApplyControlToken */
448
  schannel_QueryContextAttributes,      /* QueryContextAttributes */
449
  nullptr,                              /* ImpersonateSecurityContext */
450
  nullptr,                              /* RevertSecurityContext */
451
  schannel_MakeSignature,               /* MakeSignature */
452
  schannel_VerifySignature,             /* VerifySignature */
453
  nullptr,                              /* FreeContextBuffer */
454
  nullptr,                              /* QuerySecurityPackageInfo */
455
  nullptr,                              /* Reserved3 */
456
  nullptr,                              /* Reserved4 */
457
  nullptr,                              /* ExportSecurityContext */
458
  nullptr,                              /* ImportSecurityContext */
459
  nullptr,                              /* AddCredentials */
460
  nullptr,                              /* Reserved8 */
461
  nullptr,                              /* QuerySecurityContextToken */
462
  schannel_EncryptMessage,              /* EncryptMessage */
463
  schannel_DecryptMessage,              /* DecryptMessage */
464
  nullptr,                              /* SetContextAttributes */
465
  nullptr,                              /* SetCredentialsAttributes */
466
};
467
468
const SecurityFunctionTableW SCHANNEL_SecurityFunctionTableW = {
469
  3,                                    /* dwVersion */
470
  nullptr,                              /* EnumerateSecurityPackages */
471
  schannel_QueryCredentialsAttributesW, /* QueryCredentialsAttributes */
472
  schannel_AcquireCredentialsHandleW,   /* AcquireCredentialsHandle */
473
  schannel_FreeCredentialsHandle,       /* FreeCredentialsHandle */
474
  nullptr,                              /* Reserved2 */
475
  schannel_InitializeSecurityContextW,  /* InitializeSecurityContext */
476
  schannel_AcceptSecurityContextW,      /* AcceptSecurityContext */
477
  nullptr,                              /* CompleteAuthToken */
478
  schannel_DeleteSecurityContext,       /* DeleteSecurityContext */
479
  nullptr,                              /* ApplyControlToken */
480
  schannel_QueryContextAttributes,      /* QueryContextAttributes */
481
  nullptr,                              /* ImpersonateSecurityContext */
482
  nullptr,                              /* RevertSecurityContext */
483
  schannel_MakeSignature,               /* MakeSignature */
484
  schannel_VerifySignature,             /* VerifySignature */
485
  nullptr,                              /* FreeContextBuffer */
486
  nullptr,                              /* QuerySecurityPackageInfo */
487
  nullptr,                              /* Reserved3 */
488
  nullptr,                              /* Reserved4 */
489
  nullptr,                              /* ExportSecurityContext */
490
  nullptr,                              /* ImportSecurityContext */
491
  nullptr,                              /* AddCredentials */
492
  nullptr,                              /* Reserved8 */
493
  nullptr,                              /* QuerySecurityContextToken */
494
  schannel_EncryptMessage,              /* EncryptMessage */
495
  schannel_DecryptMessage,              /* DecryptMessage */
496
  nullptr,                              /* SetContextAttributes */
497
  nullptr,                              /* SetCredentialsAttributes */
498
};
499
500
const SecPkgInfoA SCHANNEL_SecPkgInfoA = {
501
  0x000107B3,                 /* fCapabilities */
502
  1,                          /* wVersion */
503
  0x000E,                     /* wRPCID */
504
  SCHANNEL_CB_MAX_TOKEN,      /* cbMaxToken */
505
  "Schannel",                 /* Name */
506
  "Schannel Security Package" /* Comment */
507
};
508
509
static WCHAR SCHANNEL_SecPkgInfoW_NameBuffer[32] = WINPR_C_ARRAY_INIT;
510
static WCHAR SCHANNEL_SecPkgInfoW_CommentBuffer[32] = WINPR_C_ARRAY_INIT;
511
512
const SecPkgInfoW SCHANNEL_SecPkgInfoW = {
513
  0x000107B3,                        /* fCapabilities */
514
  1,                                 /* wVersion */
515
  0x000E,                            /* wRPCID */
516
  SCHANNEL_CB_MAX_TOKEN,             /* cbMaxToken */
517
  SCHANNEL_SecPkgInfoW_NameBuffer,   /* Name */
518
  SCHANNEL_SecPkgInfoW_CommentBuffer /* Comment */
519
};
520
521
BOOL SCHANNEL_init(void)
522
0
{
523
0
  InitializeConstWCharFromUtf8(SCHANNEL_SecPkgInfoA.Name, SCHANNEL_SecPkgInfoW_NameBuffer,
524
0
                               ARRAYSIZE(SCHANNEL_SecPkgInfoW_NameBuffer));
525
0
  InitializeConstWCharFromUtf8(SCHANNEL_SecPkgInfoA.Comment, SCHANNEL_SecPkgInfoW_CommentBuffer,
526
0
                               ARRAYSIZE(SCHANNEL_SecPkgInfoW_CommentBuffer));
527
0
  return TRUE;
528
0
}