Merge pull request #5714 from alexischr/update_bockbuild
[mono.git] / mono / btls / btls-x509-lookup.c
1 //
2 //  btls-x509-lookup.c
3 //  MonoBtls
4 //
5 //  Created by Martin Baulig on 3/6/16.
6 //  Copyright © 2016 Xamarin. All rights reserved.
7 //
8
9 #include <btls-x509-lookup.h>
10 #include <btls-x509-lookup-mono.h>
11
12 struct MonoBtlsX509Lookup {
13         MonoBtlsX509LookupType type;
14         X509_LOOKUP *lookup;
15         int owns_lookup;
16         MonoBtlsX509Store *store;
17         CRYPTO_refcount_t references;
18 };
19
20 static X509_LOOKUP_METHOD *
21 get_lookup_method (MonoBtlsX509LookupType type)
22 {
23         switch (type) {
24         case MONO_BTLS_X509_LOOKUP_TYPE_FILE:
25                 return X509_LOOKUP_file ();
26         case MONO_BTLS_X509_LOOKUP_TYPE_HASH_DIR:
27                 return X509_LOOKUP_hash_dir ();
28         case MONO_BTLS_X509_LOOKUP_TYPE_MONO:
29                 return mono_btls_x509_lookup_mono_method ();
30         default:
31                 return NULL;
32         }
33 }
34
35 MONO_API MonoBtlsX509Lookup *
36 mono_btls_x509_lookup_new (MonoBtlsX509Store *store, MonoBtlsX509LookupType type)
37 {
38         MonoBtlsX509Lookup *lookup;
39         X509_LOOKUP *store_lookup;
40         X509_LOOKUP_METHOD *method;
41
42         method = get_lookup_method (type);
43         if (!method)
44                 return NULL;
45
46         lookup = OPENSSL_malloc (sizeof(MonoBtlsX509Lookup));
47         if (!lookup)
48                 return NULL;
49
50         store_lookup = X509_STORE_add_lookup (mono_btls_x509_store_peek_store (store), method);
51         if (!store_lookup) {
52                 OPENSSL_free (lookup);
53                 return NULL;
54         }
55
56         memset (lookup, 0, sizeof(MonoBtlsX509Lookup));
57         // The X509_STORE owns the X509_LOOKUP.
58         lookup->store = mono_btls_x509_store_up_ref (store);
59         lookup->lookup = store_lookup;
60         lookup->owns_lookup = 0;
61         lookup->references = 1;
62         lookup->type = type;
63         return lookup;
64 }
65
66 MONO_API int
67 mono_btls_x509_lookup_load_file (MonoBtlsX509Lookup *lookup, const char *file, MonoBtlsX509FileType type)
68 {
69         return X509_LOOKUP_load_file (lookup->lookup, file, type);
70 }
71
72 MONO_API int
73 mono_btls_x509_lookup_add_dir (MonoBtlsX509Lookup *lookup, const char *dir, MonoBtlsX509FileType type)
74 {
75         return X509_LOOKUP_add_dir (lookup->lookup, dir, type);
76 }
77
78 MONO_API MonoBtlsX509Lookup *
79 mono_btls_x509_lookup_up_ref (MonoBtlsX509Lookup *lookup)
80 {
81         CRYPTO_refcount_inc (&lookup->references);
82         return lookup;
83 }
84
85 MONO_API int
86 mono_btls_x509_lookup_free (MonoBtlsX509Lookup *lookup)
87 {
88         if (!CRYPTO_refcount_dec_and_test_zero (&lookup->references))
89                 return 0;
90
91         if (lookup->store) {
92                 mono_btls_x509_store_free (lookup->store);
93                 lookup->store = NULL;
94         }
95
96         if (lookup->lookup) {
97                 if (lookup->owns_lookup)
98                         X509_LOOKUP_free (lookup->lookup);
99                 lookup->lookup = NULL;
100         }
101
102         OPENSSL_free (lookup);
103         return 1;
104 }
105
106 MONO_API int
107 mono_btls_x509_lookup_init (MonoBtlsX509Lookup *lookup)
108 {
109         return X509_LOOKUP_init (lookup->lookup);
110 }
111
112 MONO_API int
113 mono_btls_x509_lookup_shutdown (MonoBtlsX509Lookup *lookup)
114 {
115         return X509_LOOKUP_shutdown (lookup->lookup);
116 }
117
118 MONO_API MonoBtlsX509LookupType
119 mono_btls_x509_lookup_get_type (MonoBtlsX509Lookup *lookup)
120 {
121         return lookup->type;
122 }
123
124 MONO_API X509_LOOKUP *
125 mono_btls_x509_lookup_peek_lookup (MonoBtlsX509Lookup *lookup)
126 {
127         return lookup->lookup;
128 }
129
130 MONO_API X509 *
131 mono_btls_x509_lookup_by_subject (MonoBtlsX509Lookup *lookup, MonoBtlsX509Name *name)
132 {
133         X509_OBJECT obj;
134         X509 *x509;
135         int ret;
136
137         ret = X509_LOOKUP_by_subject (lookup->lookup, X509_LU_X509, mono_btls_x509_name_peek_name (name), &obj);
138         if (ret != X509_LU_X509) {
139                 X509_OBJECT_free_contents (&obj);
140                 return NULL;
141         }
142
143         x509 = X509_up_ref (obj.data.x509);
144         return x509;
145 }
146
147 MONO_API X509 *
148 mono_btls_x509_lookup_by_fingerprint (MonoBtlsX509Lookup *lookup, unsigned char *bytes, int len)
149 {
150         X509_OBJECT obj;
151         X509 *x509;
152         int ret;
153
154         ret = X509_LOOKUP_by_fingerprint (lookup->lookup, X509_LU_X509, bytes, len, &obj);
155         if (ret != X509_LU_X509) {
156                 X509_OBJECT_free_contents (&obj);
157                 return NULL;
158         }
159
160         x509 = X509_up_ref (obj.data.x509);
161         return x509;
162 }