forked from nic-at/httptapi
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcrypt.c
More file actions
278 lines (248 loc) · 6.97 KB
/
crypt.c
File metadata and controls
278 lines (248 loc) · 6.97 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
/*++
Copyright 2009-2012 IPcom GmbH
Copyright 1995 - 2000 Microsoft Corporation
Module Name: crypt.c
Simple de-/encryption functions, e.g. to store passwords encrypted in the registry
--*/
#include <windows.h>
#include <Wincrypt.h>
#include "crypt.h"
#include "tapi_logging.h"
char* decryptString(const char *szencryptedString) {
BOOL ret;
DWORD bufflen;
char *buff;
HCRYPTPROV hProv;
HCRYPTKEY hKey;
LOG((5,"decryptString ..."));
ret = CryptStringToBinary(
szencryptedString,
0,
CRYPT_STRING_BASE64,
0,
&bufflen,
0,
0);
if (ret == FALSE) {
LOG((1,"decryptString: error calculating base64-deconding buffer size"));
return NULL;
}
if ( !(buff = (char *) LocalAlloc(LPTR, bufflen*sizeof(BYTE) + 1)) ) {
LOG((1,"decryptString: error allocating %d bytes",
bufflen*sizeof(BYTE) + 1));
return NULL;
}
ret = CryptStringToBinary(
szencryptedString,
0,
CRYPT_STRING_BASE64,
(BYTE *) buff,
&bufflen,
0,
0);
if (ret == FALSE) {
LOG((1,"decryptString: error while base64 decoding"));
return NULL;
}
// Acquire a handle to the CSP.
if(!CryptAcquireContext(
&hProv,
NULL,
MS_ENHANCED_PROV,
PROV_RSA_FULL,
CRYPT_VERIFYCONTEXT))
{
// If the key container cannot be opened, try creating a new
// container by specifying a container name and setting the
// CRYPT_NEWKEYSET flag.
if(NTE_BAD_KEYSET == GetLastError())
{
if(!CryptAcquireContext(
&hProv,
"mytestcontainer",
MS_ENHANCED_PROV,
PROV_RSA_FULL,
CRYPT_NEWKEYSET | CRYPT_VERIFYCONTEXT))
{
LOG((1,"decryptString: Error in AcquireContext (with new container) 0x%08x",GetLastError()));
if (buff) LocalFree(buff);
return NULL;
}
}
else
{
LOG((1,"decryptString: Error in AcquireContext 0x%08x",GetLastError()));
if (buff) LocalFree(buff);
return NULL;
}
}
// Use the CryptImportKey function to import the PLAINTEXTKEYBLOB
// BYTE array into the key container. The function returns a
// pointer to an HCRYPTKEY variable that contains the handle of
// the imported key.
if (!CryptImportKey(
hProv,
SimpleDesKeyBlob,
sizeof(SimpleDesKeyBlob),
0,
CRYPT_EXPORTABLE,
&hKey ) )
{
LOG((1,"decryptString: Error 0x%08x in importing the Des key",GetLastError()));
if (buff) LocalFree(buff);
if (hProv) CryptReleaseContext(hProv, 0);
return NULL;
}
if (!CryptDecrypt(
hKey, //__in HCRYPTKEY hKey,
0, //__in HCRYPTHASH hHash,
TRUE, //__in BOOL Final,
0, //__in DWORD dwFlags,
(BYTE *) buff, //__inout BYTE *pbData,
&bufflen //__inout DWORD *pdwDataLen
) )
{
LOG((1,"decryptString: Error 0x%08x during decryption",GetLastError()));
if (buff) LocalFree(buff);
if (hProv) CryptReleaseContext(hProv, 0);
return NULL;
}
if (hProv) CryptReleaseContext(hProv, 0);
// Note: We expect that original string was zero terminate before decoding,
// so the decrypted string is also zero terminated.
return buff;
};
char* encryptString(const char *szplainString) {
// hProv: Cryptographic service provider (CSP). This example
// uses the Microsoft Enhanced Cryptographic
// Provider.
// hKey: Key to be used. In this example, you import the
// key as a PLAINTEXTKEYBLOB.
HCRYPTPROV hProv = (HCRYPTPROV) NULL;
HCRYPTKEY hKey = (HCRYPTKEY) NULL;
DWORD bufflen;
LPTSTR buff = 0;
BYTE * pbData = 0;
DWORD dwDataLen, dwBufLen;
// Acquire a handle to the CSP.
if(!CryptAcquireContext(
&hProv,
NULL,
MS_ENHANCED_PROV,
PROV_RSA_FULL,
CRYPT_VERIFYCONTEXT))
{
// If the key container cannot be opened, try creating a new
// container by specifying a container name and setting the
// CRYPT_NEWKEYSET flag.
if(NTE_BAD_KEYSET == GetLastError())
{
if(!CryptAcquireContext(
&hProv,
"mytestcontainer",
MS_ENHANCED_PROV,
PROV_RSA_FULL,
CRYPT_NEWKEYSET | CRYPT_VERIFYCONTEXT))
{
LOG((1,"encryptString: Error in AcquireContext (with new container) 0x%08x",GetLastError()));
return NULL;
}
} else {
LOG((1,"encryptString: Error in AcquireContext 0x%08x",GetLastError()));
return NULL;
}
}
LOG((5,"encryptString: AcquireContext succeeded"));
// Use the CryptImportKey function to import the PLAINTEXTKEYBLOB
// BYTE array into the key container. The function returns a
// pointer to an HCRYPTKEY variable that contains the handle of
// the imported key.
if (!CryptImportKey(
hProv,
SimpleDesKeyBlob,
sizeof(SimpleDesKeyBlob),
0,
CRYPT_EXPORTABLE,
&hKey ) )
{
LOG((1,"decryptString: Error 0x%08x in importing the Des key",GetLastError()));
goto cleanup;
}
LOG((5,"encryptString: CryptImportKey succeeded"));
// During encryption, the result can be longer then the input
// Thus, calculate the needed buffer length
dwBufLen = (DWORD) strlen(szplainString) + 1;
if (!CryptEncrypt(
hKey, //__in HCRYPTKEY hKey,
0, //__in HCRYPTHASH hHash,
TRUE, //__in BOOL Final,
0, //__in DWORD dwFlags,
0, //__inout BYTE *pbData,
&dwBufLen, //__inout DWORD *pdwDataLen,
0 //__in DWORD dwBufLen
) )
{
LOG((1,"decryptString: Error 0x%08x during encryption calculation",GetLastError()));
goto cleanup;
}
LOG((5,"encryptString: CryptEncrypt1 succeeded"));
if ( dwBufLen < (strlen(szplainString) + 1) ) {
dwBufLen = (DWORD) (strlen(szplainString) + 1);
}
if ( !(pbData = (BYTE *) LocalAlloc(LPTR, dwBufLen)) ) {
LOG((1,"decryptString: error allocating %d bytes", dwBufLen));
goto cleanup;
}
// copy the original into the new buffer as it will be destroyed during encrpytion
dwDataLen = (DWORD) strlen(szplainString) + 1;
memcpy(pbData, szplainString, dwDataLen);
if (!CryptEncrypt(
hKey, //__in HCRYPTKEY hKey,
0, //__in HCRYPTHASH hHash,
TRUE, //__in BOOL Final,
0, //__in DWORD dwFlags,
pbData, //__inout BYTE *pbData,
&dwDataLen, //__inout DWORD *pdwDataLen,
dwBufLen //__in DWORD dwBufLen
) )
{
LOG((1,"decryptString: Error 0x%08x during encryption"));
goto cleanup;
}
LOG((5,"encryptString: CryptEncrypt2 succeeded"));
// Encrypted Key steht nun pbData --> nun machen wir daraus Base64!
// 1. calculate length
if (!CryptBinaryToString(
pbData,
dwDataLen,
CRYPT_STRING_BASE64,
NULL,
&bufflen)) {
LOG((1,"decryptString: Error calculating base64 length"));
goto cleanup;
}
LOG((5,"encryptString: CryptBinaryToString1 succeeded"));
if ( !(buff = (LPTSTR) LocalAlloc(LPTR, bufflen*sizeof(TCHAR))) ) {
LOG((1,"decryptString: error allocating %d bytes for base64 encoding", bufflen*sizeof(TCHAR) ));
goto cleanup;
}
// 2. encode with base64
if (!CryptBinaryToString(
pbData,
dwDataLen,
CRYPT_STRING_BASE64,
buff,
&bufflen)) {
LOG((1,"decryptString: Error converting to base64"));
if (buff) {
LocalFree(buff);
buff = NULL;
}
goto cleanup;
}
LOG((5,"encryptString: CryptBinaryToString2 succeeded"));
cleanup:
if (pbData) LocalFree(pbData);
if (hProv) CryptReleaseContext(hProv, 0);
return buff;
}