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 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 */
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
);