[2019-12] [threads] Add back mono_threads_attach_tools_thread as a public API (#18074)
[mono-project.git] / mono / btls / btls-x509-lookup-mono.c
blob40cbddd53fde2aca5c7229d2b9f167391229d26b
1 //
2 // btls-x509-lookup-mono.c
3 // MonoBtls
4 //
5 // Created by Martin Baulig on 3/6/16.
6 // Copyright © 2016 Xamarin. All rights reserved.
7 //
9 #include "btls-x509-lookup.h"
10 #include "btls-x509-lookup-mono.h"
11 #include <openssl/stack.h>
13 // random high number
14 #define MONO_BTLS_X509_L_MONO_ADD 36292
16 typedef struct MonoLookupNode MonoLookupNode;
17 struct MonoLookupNode {
18 MonoBtlsX509LookupMono *mono;
19 MonoLookupNode *next;
22 typedef struct {
23 MonoLookupNode *nodes;
24 } MonoLookup;
26 struct MonoBtlsX509LookupMono {
27 const void *instance;
28 MonoBtlsX509LookupMono_BySubject by_subject_func;
29 MonoLookup *lookup;
32 MonoBtlsX509LookupMono *
33 mono_btls_x509_lookup_mono_new (void)
35 MonoBtlsX509LookupMono *mono;
37 mono = OPENSSL_malloc (sizeof (MonoBtlsX509LookupMono));
38 if (!mono)
39 return NULL;
41 memset (mono, 0, sizeof (MonoBtlsX509LookupMono));
42 return mono;
45 void
46 mono_btls_x509_lookup_mono_init (MonoBtlsX509LookupMono *mono, const void *instance,
47 MonoBtlsX509LookupMono_BySubject by_subject_func)
49 mono->instance = instance;
50 mono->by_subject_func = by_subject_func;
53 static int
54 mono_lookup_install (MonoLookup *lookup, MonoBtlsX509LookupMono *mono)
56 MonoLookupNode *node;
58 node = OPENSSL_malloc (sizeof (MonoLookupNode));
59 if (!node)
60 return 0;
62 memset (node, 0, sizeof (MonoLookupNode));
63 mono->lookup = lookup;
64 node->mono = mono;
65 node->next = lookup->nodes;
66 lookup->nodes = node;
67 return 1;
70 static int
71 mono_lookup_uninstall (MonoBtlsX509LookupMono *mono)
73 MonoLookupNode **ptr;
75 if (!mono->lookup)
76 return 0;
78 for (ptr = &mono->lookup->nodes; *ptr; ptr = &(*ptr)->next) {
79 if ((*ptr)->mono == mono) {
80 *ptr = (*ptr)->next;
81 return 1;
85 return 0;
88 int
89 mono_btls_x509_lookup_mono_free (MonoBtlsX509LookupMono *mono)
91 mono->instance = NULL;
92 mono->by_subject_func = NULL;
94 if (mono->lookup) {
95 if (!mono_lookup_uninstall (mono))
96 return 0;
99 mono->lookup = NULL;
101 OPENSSL_free (mono);
102 return 1;
105 static int
106 mono_lookup_ctrl (X509_LOOKUP *ctx, int cmd, const char *argp, long argl, char **ret)
108 MonoLookup *lookup = (MonoLookup*)ctx->method_data;
109 MonoBtlsX509LookupMono *mono = (MonoBtlsX509LookupMono*)argp;
111 if (!lookup || cmd != MONO_BTLS_X509_L_MONO_ADD)
112 return 0;
113 if (!mono || mono->lookup)
114 return 0;
116 return mono_lookup_install (lookup, mono);
119 static int
120 mono_lookup_new (X509_LOOKUP *ctx)
122 MonoLookup *data;
124 data = OPENSSL_malloc (sizeof (MonoLookup));
125 if (!data)
126 return 0;
128 memset (data, 0, sizeof (MonoLookup));
129 ctx->method_data = (void *)data;
130 return 1;
133 static void
134 mono_lookup_free (X509_LOOKUP *ctx)
136 MonoLookup *lookup;
137 MonoLookupNode *ptr;
139 lookup = (MonoLookup *)ctx->method_data;
140 ctx->method_data = NULL;
141 if (!lookup)
142 return;
144 ptr = lookup->nodes;
145 lookup->nodes = NULL;
147 while (ptr) {
148 MonoLookupNode *node = ptr;
149 ptr = ptr->next;
151 if (node->mono)
152 node->mono->lookup = NULL;
153 node->mono = NULL;
154 node->next = NULL;
155 OPENSSL_free (node);
158 OPENSSL_free (lookup);
161 static int
162 mono_lookup_get_by_subject (X509_LOOKUP *ctx, int type, X509_NAME *name, X509_OBJECT *obj_ret)
164 MonoLookup *lookup;
165 MonoBtlsX509Name *name_obj;
166 MonoLookupNode *node;
167 X509 *x509 = NULL;
168 int ret = 0;
170 lookup = (MonoLookup *)ctx->method_data;
172 if (!lookup || !lookup->nodes)
173 return 0;
174 if (type != X509_LU_X509)
175 return 0;
177 name_obj = mono_btls_x509_name_from_name (name);
178 x509 = NULL;
180 for (node = lookup->nodes; node; node = node->next) {
181 if (!node->mono || !node->mono->by_subject_func)
182 continue;
183 ret = (* node->mono->by_subject_func) (node->mono->instance, name_obj, &x509);
184 if (ret)
185 break;
188 mono_btls_x509_name_free (name_obj);
190 if (!ret) {
191 if (x509)
192 X509_free(x509);
193 return 0;
196 obj_ret->type = X509_LU_X509;
197 obj_ret->data.x509 = x509;
198 return 1;
201 static X509_LOOKUP_METHOD mono_lookup_method = {
202 "Mono lookup method",
203 mono_lookup_new, /* new */
204 mono_lookup_free, /* free */
205 NULL, /* init */
206 NULL, /* shutdown */
207 mono_lookup_ctrl, /* ctrl */
208 mono_lookup_get_by_subject, /* get_by_subject */
209 NULL, /* get_by_issuer_serial */
210 NULL, /* get_by_fingerprint */
211 NULL, /* get_by_alias */
214 X509_LOOKUP_METHOD *
215 mono_btls_x509_lookup_mono_method (void)
217 return &mono_lookup_method;
221 mono_btls_x509_lookup_add_mono (MonoBtlsX509Lookup *lookup, MonoBtlsX509LookupMono *mono)
223 if (mono_btls_x509_lookup_get_type (lookup) != MONO_BTLS_X509_LOOKUP_TYPE_MONO)
224 return 0;
225 return X509_LOOKUP_ctrl (mono_btls_x509_lookup_peek_lookup (lookup),
226 MONO_BTLS_X509_L_MONO_ADD,
227 (void*)mono, 0, NULL);