2 // btls-x509-lookup-mono.c
5 // Created by Martin Baulig on 3/6/16.
6 // Copyright © 2016 Xamarin. All rights reserved.
9 #include <btls-x509-lookup.h>
10 #include <btls-x509-lookup-mono.h>
11 #include <openssl/stack.h>
14 #define MONO_BTLS_X509_L_MONO_ADD 36292
16 typedef struct MonoLookupNode MonoLookupNode;
17 struct MonoLookupNode {
18 MonoBtlsX509LookupMono *mono;
23 MonoLookupNode *nodes;
26 struct MonoBtlsX509LookupMono {
28 MonoBtlsX509LookupMono_BySubject by_subject_func;
32 MONO_API MonoBtlsX509LookupMono *
33 mono_btls_x509_lookup_mono_new (void)
35 MonoBtlsX509LookupMono *mono;
37 mono = OPENSSL_malloc (sizeof (MonoBtlsX509LookupMono));
41 memset (mono, 0, sizeof (MonoBtlsX509LookupMono));
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;
54 mono_lookup_install (MonoLookup *lookup, MonoBtlsX509LookupMono *mono)
58 node = OPENSSL_malloc (sizeof (MonoLookupNode));
62 memset (node, 0, sizeof (MonoLookupNode));
63 mono->lookup = lookup;
65 node->next = lookup->nodes;
71 mono_lookup_uninstall (MonoBtlsX509LookupMono *mono)
78 for (ptr = &mono->lookup->nodes; *ptr; ptr = &(*ptr)->next) {
79 if ((*ptr)->mono == mono) {
89 mono_btls_x509_lookup_mono_free (MonoBtlsX509LookupMono *mono)
91 mono->instance = NULL;
92 mono->by_subject_func = NULL;
95 if (!mono_lookup_uninstall (mono))
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)
113 if (!mono || mono->lookup)
116 return mono_lookup_install (lookup, mono);
120 mono_lookup_new (X509_LOOKUP *ctx)
124 data = OPENSSL_malloc (sizeof (MonoLookup));
128 memset (data, 0, sizeof (MonoLookup));
129 ctx->method_data = (void *)data;
134 mono_lookup_free (X509_LOOKUP *ctx)
139 lookup = (MonoLookup *)ctx->method_data;
140 ctx->method_data = NULL;
145 lookup->nodes = NULL;
148 MonoLookupNode *node = ptr;
152 node->mono->lookup = NULL;
158 OPENSSL_free (lookup);
162 mono_lookup_get_by_subject (X509_LOOKUP *ctx, int type, X509_NAME *name, X509_OBJECT *obj_ret)
165 MonoBtlsX509Name *name_obj;
166 MonoLookupNode *node;
170 lookup = (MonoLookup *)ctx->method_data;
172 if (!lookup || !lookup->nodes)
174 if (type != X509_LU_X509)
177 name_obj = mono_btls_x509_name_from_name (name);
180 for (node = lookup->nodes; node; node = node->next) {
181 if (!node->mono || !node->mono->by_subject_func)
183 ret = (* node->mono->by_subject_func) (node->mono->instance, name_obj, &x509);
188 mono_btls_x509_name_free (name_obj);
196 obj_ret->type = X509_LU_X509;
197 obj_ret->data.x509 = x509;
201 static X509_LOOKUP_METHOD mono_lookup_method = {
202 "Mono lookup method",
203 mono_lookup_new, /* new */
204 mono_lookup_free, /* free */
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 MONO_API 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)
225 return X509_LOOKUP_ctrl (mono_btls_x509_lookup_peek_lookup (lookup),
226 MONO_BTLS_X509_L_MONO_ADD,
227 (void*)mono, 0, NULL);