21#include <winpr/config.h>
23#include <winpr/cred.h>
24#include <winpr/error.h>
25#include <winpr/wlog.h>
28#define TAG WINPR_TAG("Cred")
37static BYTE char_decode(
char c)
39 if (c >=
'A' && c <=
'Z')
40 return (BYTE)(c -
'A');
41 if (c >=
'a' && c <=
'z')
42 return (BYTE)(c -
'a' + 26);
43 if (c >=
'0' && c <=
'9')
44 return (BYTE)(c -
'0' + 52);
52static BOOL cred_decode(
const char* cred,
size_t len, BYTE* buf)
59 BYTE c0 = char_decode(p[0]);
63 BYTE c1 = char_decode(p[1]);
67 BYTE c2 = char_decode(p[2]);
71 BYTE c3 = char_decode(p[3]);
75 buf[i + 0] = (BYTE)((c1 << 6) | c0);
76 buf[i + 1] = (BYTE)((c2 << 4) | (c1 >> 2));
77 buf[i + 2] = (BYTE)((c3 << 2) | (c2 >> 4));
85 BYTE c0 = char_decode(p[0]);
89 BYTE c1 = char_decode(p[1]);
93 BYTE c2 = char_decode(p[2]);
97 buf[i + 0] = (BYTE)((c1 << 6) | c0);
98 buf[i + 1] = (BYTE)((c2 << 4) | (c1 >> 2));
102 BYTE c0 = char_decode(p[0]);
106 BYTE c1 = char_decode(p[1]);
110 buf[i + 0] = (BYTE)((c1 << 6) | c0);
114 WLog_ERR(TAG,
"invalid string length");
120static size_t cred_encode(
const BYTE* bin,
size_t len,
char* cred,
size_t credlen)
122 static const char encodingChars[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
123 "abcdefghijklmnopqrstuvwxyz"
133 cred[n++] = encodingChars[bin[offset] & 0x3f];
134 BYTE x = (bin[offset] & 0xc0) >> 6;
139 cred[n++] = encodingChars[x];
145 cred[n++] = encodingChars[((bin[offset] & 0xf) << 2) | x];
146 x = (bin[offset] & 0xf0) >> 4;
151 cred[n++] = encodingChars[x];
157 cred[n++] = encodingChars[((bin[offset] & 0x3) << 4) | x];
161 cred[n++] = encodingChars[(bin[offset] & 0xfc) >> 2];
167BOOL CredMarshalCredentialW(CRED_MARSHAL_TYPE CredType, PVOID Credential,
168 LPWSTR* MarshaledCredential)
171 if (!CredMarshalCredentialA(CredType, Credential, &b) || !b)
174 *MarshaledCredential = ConvertUtf8ToWCharAlloc(b, NULL);
176 return (*MarshaledCredential != NULL);
179BOOL CredMarshalCredentialA(CRED_MARSHAL_TYPE CredType, PVOID Credential,
180 LPSTR* MarshaledCredential)
185 !MarshaledCredential)
187 SetLastError(ERROR_INVALID_PARAMETER);
195 char buffer[3ULL + (
sizeof(cert->rgbHashOfCert) * 4 / 3) +
198 const char c = WINPR_ASSERTING_INT_CAST(
char,
'A' + CredType);
199 (void)_snprintf(buffer,
sizeof(buffer),
"@@%c", c);
200 size_t len = cred_encode(cert->rgbHashOfCert,
sizeof(cert->rgbHashOfCert), &buffer[3],
202 *MarshaledCredential = strndup(buffer, len + 3);
206 WLog_ERR(TAG,
"unhandled type 0x%x", CredType);
207 SetLastError(ERROR_INVALID_PARAMETER);
212BOOL CredUnmarshalCredentialW(LPCWSTR cred, PCRED_MARSHAL_TYPE pcredType, PVOID* out)
216 str = ConvertWCharToUtf8Alloc(cred, NULL);
217 const BOOL rc = CredUnmarshalCredentialA(str, pcredType, out);
222BOOL CredUnmarshalCredentialA(LPCSTR cred, PCRED_MARSHAL_TYPE CredType, PVOID* Credential)
226 SetLastError(ERROR_INVALID_PARAMETER);
230 const size_t len = strlen(cred);
231 if ((len < 3) || !CredType || !Credential || (cred[0] !=
'@') || (cred[1] !=
'@'))
233 SetLastError(ERROR_INVALID_PARAMETER);
237 BYTE b = char_decode(cred[2]);
238 if (!b || (b > BinaryBlobForSystem))
240 SetLastError(ERROR_INVALID_PARAMETER);
244 *CredType = (CRED_MARSHAL_TYPE)b;
250 BYTE hash[CERT_HASH_LENGTH] = { 0 };
252 if ((len != 30) || !cred_decode(&cred[3], len - 3, hash))
254 SetLastError(ERROR_INVALID_PARAMETER);
263 memcpy(cert->rgbHashOfCert, hash,
sizeof(cert->rgbHashOfCert));
268 WLog_ERR(TAG,
"unhandled credType 0x%x", *CredType);
269 SetLastError(ERROR_INVALID_PARAMETER);
275BOOL CredIsMarshaledCredentialW(LPCWSTR MarshaledCredential)
277 CRED_MARSHAL_TYPE t = BinaryBlobForSystem;
280 BOOL ret = CredUnmarshalCredentialW(MarshaledCredential, &t, &out);
287BOOL CredIsMarshaledCredentialA(LPCSTR MarshaledCredential)
289 CRED_MARSHAL_TYPE t = BinaryBlobForSystem;
291 BOOL ret = CredUnmarshalCredentialA(MarshaledCredential, &t, &out);
298VOID CredFree(PVOID Buffer)