FreeRDP
sspi_gss.c
1 
22 #include <winpr/crt.h>
23 #include <winpr/assert.h>
24 #include <winpr/endian.h>
25 #include <winpr/asn1.h>
26 #include <winpr/stream.h>
27 
28 #include "sspi_gss.h"
29 
30 BOOL sspi_gss_wrap_token(SecBuffer* buf, const WinPrAsn1_OID* oid, uint16_t tok_id,
31  const sspi_gss_data* token)
32 {
33  WinPrAsn1Encoder* enc = NULL;
34  BYTE tok_id_buf[2];
35  WinPrAsn1_MemoryChunk mc = { 2, tok_id_buf };
36  wStream s;
37  size_t len = 0;
38  BOOL ret = FALSE;
39 
40  WINPR_ASSERT(buf);
41  WINPR_ASSERT(oid);
42  WINPR_ASSERT(token);
43 
44  Data_Write_UINT16_BE(tok_id_buf, tok_id);
45 
46  enc = WinPrAsn1Encoder_New(WINPR_ASN1_DER);
47  if (!enc)
48  return FALSE;
49 
50  /* initialContextToken [APPLICATION 0] */
51  if (!WinPrAsn1EncAppContainer(enc, 0))
52  goto cleanup;
53 
54  /* thisMech OID */
55  if (!WinPrAsn1EncOID(enc, oid))
56  goto cleanup;
57 
58  /* TOK_ID */
59  if (!WinPrAsn1EncRawContent(enc, &mc))
60  goto cleanup;
61 
62  /* innerToken */
63  mc.data = (BYTE*)token->data;
64  mc.len = token->length;
65  if (!WinPrAsn1EncRawContent(enc, &mc))
66  goto cleanup;
67 
68  if (!WinPrAsn1EncEndContainer(enc))
69  goto cleanup;
70 
71  if (!WinPrAsn1EncStreamSize(enc, &len) || len > buf->cbBuffer)
72  goto cleanup;
73 
74  Stream_StaticInit(&s, buf->pvBuffer, len);
75  if (WinPrAsn1EncToStream(enc, &s))
76  {
77  buf->cbBuffer = (UINT32)len;
78  ret = TRUE;
79  }
80 
81 cleanup:
82  WinPrAsn1Encoder_Free(&enc);
83  return ret;
84 }
85 
86 BOOL sspi_gss_unwrap_token(const SecBuffer* buf, WinPrAsn1_OID* oid, uint16_t* tok_id,
87  sspi_gss_data* token)
88 {
89  WinPrAsn1Decoder dec;
90  WinPrAsn1Decoder dec2;
91  WinPrAsn1_tagId tag = 0;
92  wStream sbuffer = { 0 };
93  wStream* s = NULL;
94 
95  WINPR_ASSERT(buf);
96  WINPR_ASSERT(oid);
97  WINPR_ASSERT(token);
98 
99  WinPrAsn1Decoder_InitMem(&dec, WINPR_ASN1_DER, buf->pvBuffer, buf->cbBuffer);
100 
101  if (!WinPrAsn1DecReadApp(&dec, &tag, &dec2) || tag != 0)
102  return FALSE;
103 
104  if (!WinPrAsn1DecReadOID(&dec2, oid, FALSE))
105  return FALSE;
106 
107  sbuffer = WinPrAsn1DecGetStream(&dec2);
108  s = &sbuffer;
109 
110  if (Stream_Length(s) < 2)
111  return FALSE;
112 
113  if (tok_id)
114  Stream_Read_INT16_BE(s, *tok_id);
115 
116  token->data = Stream_Pointer(s);
117  token->length = (UINT)Stream_GetRemainingLength(s);
118 
119  return TRUE;
120 }