FreeRDP
Loading...
Searching...
No Matches
certificate_store.c
1
23#include <freerdp/config.h>
24
25#include <winpr/assert.h>
26#include <errno.h>
27#include <stdio.h>
28#include <string.h>
29#include <ctype.h>
30
31#include <winpr/crypto.h>
32#include <winpr/crt.h>
33#include <winpr/file.h>
34#include <winpr/path.h>
35
36#include <freerdp/settings.h>
37
38#include <freerdp/crypto/crypto.h>
39#include <freerdp/crypto/certificate_store.h>
40#include <freerdp/log.h>
41
42struct rdp_certificate_store
43{
44 char* certs_path;
45 char* server_path;
46};
47
48static const char certificate_store_dir[] = "certs";
49static const char certificate_server_dir[] = "server";
50
51static char* freerdp_certificate_store_file_path(const rdpCertificateStore* store, const char* hash)
52{
53 const char* hosts = freerdp_certificate_store_get_hosts_path(store);
54
55 if (!hosts || !hash)
56 return NULL;
57
58 return GetCombinedPath(hosts, hash);
59}
60
61freerdp_certificate_store_result
62freerdp_certificate_store_contains_data(rdpCertificateStore* store, const rdpCertificateData* data)
63{
64 freerdp_certificate_store_result rc = CERT_STORE_NOT_FOUND;
65 const char* host = freerdp_certificate_data_get_host(data);
66 const UINT16 port = freerdp_certificate_data_get_port(data);
67
68 rdpCertificateData* loaded = freerdp_certificate_store_load_data(store, host, port);
69 if (!loaded)
70 goto fail;
71
72 rc = freerdp_certificate_data_equal(data, loaded) ? CERT_STORE_MATCH : CERT_STORE_MISMATCH;
73
74fail:
75 freerdp_certificate_data_free(loaded);
76 return rc;
77}
78
79BOOL freerdp_certificate_store_remove_data(rdpCertificateStore* store,
80 const rdpCertificateData* data)
81{
82 BOOL rc = TRUE;
83
84 WINPR_ASSERT(store);
85
86 const char* hash = freerdp_certificate_data_get_hash(data);
87 if (!hash)
88 return FALSE;
89 char* path = freerdp_certificate_store_file_path(store, hash);
90
91 if (!path)
92 return FALSE;
93
94 if (winpr_PathFileExists(path))
95 rc = winpr_DeleteFile(path);
96 free(path);
97 return rc;
98}
99
100BOOL freerdp_certificate_store_save_data(rdpCertificateStore* store, const rdpCertificateData* data)
101{
102 BOOL rc = FALSE;
103 const char* base = freerdp_certificate_store_get_hosts_path(store);
104 const char* hash = freerdp_certificate_data_get_hash(data);
105 char* path = freerdp_certificate_store_file_path(store, hash);
106 FILE* fp = NULL;
107
108 if (!winpr_PathFileExists(base))
109 {
110 if (!winpr_PathMakePath(base, NULL))
111 goto fail;
112 }
113
114 fp = winpr_fopen(path, "w");
115 if (!fp)
116 goto fail;
117
118 (void)fprintf(fp, "%s", freerdp_certificate_data_get_pem_ex(data, FALSE));
119
120 rc = TRUE;
121fail:
122 if (fp)
123 (void)fclose(fp);
124 free(path);
125 return rc;
126}
127
128rdpCertificateData* freerdp_certificate_store_load_data(rdpCertificateStore* store,
129 const char* host, UINT16 port)
130{
131 char* path = NULL;
132 rdpCertificateData* data = NULL;
133
134 WINPR_ASSERT(store);
135
136 path = freerdp_certificate_store_get_cert_path(store, host, port);
137 if (!path)
138 goto fail;
139
140 data = freerdp_certificate_data_new_from_file(host, port, path);
141
142fail:
143 free(path);
144 return data;
145}
146
147rdpCertificateStore* freerdp_certificate_store_new(const rdpSettings* settings)
148{
149 rdpCertificateStore* store = (rdpCertificateStore*)calloc(1, sizeof(rdpCertificateStore));
150
151 if (!store)
152 return NULL;
153
154 const char* base = freerdp_settings_get_string(settings, FreeRDP_ConfigPath);
155 if (!base)
156 goto fail;
157
158 store->certs_path = GetCombinedPath(base, certificate_store_dir);
159 store->server_path = GetCombinedPath(base, certificate_server_dir);
160 if (!store->certs_path || !store->server_path)
161 goto fail;
162
163 return store;
164
165fail:
166 WINPR_PRAGMA_DIAG_PUSH
167 WINPR_PRAGMA_DIAG_IGNORED_MISMATCHED_DEALLOC
168 freerdp_certificate_store_free(store);
169 WINPR_PRAGMA_DIAG_POP
170 return NULL;
171}
172
173void freerdp_certificate_store_free(rdpCertificateStore* store)
174{
175 if (!store)
176 return;
177
178 free(store->certs_path);
179 free(store->server_path);
180 free(store);
181}
182
183const char* freerdp_certificate_store_get_certs_path(const rdpCertificateStore* store)
184{
185 WINPR_ASSERT(store);
186 return store->certs_path;
187}
188
189const char* freerdp_certificate_store_get_hosts_path(const rdpCertificateStore* store)
190{
191 WINPR_ASSERT(store);
192 return store->server_path;
193}
194
195char* freerdp_certificate_store_get_cert_path(const rdpCertificateStore* store, const char* host,
196 UINT16 port)
197{
198 WINPR_ASSERT(store);
199
200 char* hash = freerdp_certificate_data_hash(host, port);
201 if (!hash)
202 return NULL;
203 char* path = freerdp_certificate_store_file_path(store, hash);
204 free(hash);
205 return path;
206}
FREERDP_API const char * freerdp_settings_get_string(const rdpSettings *settings, FreeRDP_Settings_Keys_String id)
Returns a immutable string settings value.