[tests] Test loading references from LoadFrom and LoadFile contexts
[mono-project.git] / mono / btls / btls-x509-store-ctx.c
blobf0d8ace40d76b19966d1b53d461bfa1e23d445d0
1 //
2 // btls-x509-store-ctx.c
3 // MonoBtls
4 //
5 // Created by Martin Baulig on 3/5/16.
6 // Copyright © 2016 Xamarin. All rights reserved.
7 //
9 #include "btls-x509-store-ctx.h"
11 struct MonoBtlsX509StoreCtx {
12 int owns;
13 X509_STORE_CTX *ctx;
14 CRYPTO_refcount_t references;
15 MonoBtlsX509Store *store;
16 MonoBtlsX509Chain *chain;
19 MONO_API MonoBtlsX509StoreCtx *
20 mono_btls_x509_store_ctx_from_ptr (X509_STORE_CTX *ptr)
22 MonoBtlsX509StoreCtx *ctx;
24 ctx = OPENSSL_malloc (sizeof(MonoBtlsX509StoreCtx));
25 if (!ctx)
26 return NULL;
28 memset (ctx, 0, sizeof (MonoBtlsX509StoreCtx));
29 ctx->ctx = ptr;
30 ctx->references = 1;
31 return ctx;
34 MONO_API MonoBtlsX509StoreCtx *
35 mono_btls_x509_store_ctx_new (void)
37 MonoBtlsX509StoreCtx *ctx;
39 ctx = OPENSSL_malloc (sizeof(MonoBtlsX509StoreCtx));
40 if (!ctx)
41 return NULL;
43 memset (ctx, 0, sizeof (MonoBtlsX509StoreCtx));
44 ctx->ctx = X509_STORE_CTX_new ();
45 ctx->references = 1;
46 ctx->owns = 1;
47 return ctx;
50 MONO_API MonoBtlsX509StoreCtx *
51 mono_btls_x509_store_ctx_up_ref (MonoBtlsX509StoreCtx *ctx)
53 CRYPTO_refcount_inc (&ctx->references);
54 return ctx;
57 MONO_API int
58 mono_btls_x509_store_ctx_free (MonoBtlsX509StoreCtx *ctx)
60 if (!CRYPTO_refcount_dec_and_test_zero (&ctx->references))
61 return 0;
63 if (ctx->owns) {
64 X509_STORE_CTX_cleanup (ctx->ctx);
65 X509_STORE_CTX_free (ctx->ctx);
66 ctx->owns = 0;
68 if (ctx->store) {
69 mono_btls_x509_store_free (ctx->store);
70 ctx->store = NULL;
72 if (ctx->chain) {
73 mono_btls_x509_chain_free (ctx->chain);
74 ctx->chain = NULL;
76 OPENSSL_free (ctx);
77 return 1;
80 MONO_API int
81 mono_btls_x509_store_ctx_get_error (MonoBtlsX509StoreCtx *ctx, const char **error_string)
83 int error;
85 error = X509_STORE_CTX_get_error (ctx->ctx);
86 if (error_string)
87 *error_string = X509_verify_cert_error_string (error);
88 return error;
91 MONO_API int
92 mono_btls_x509_store_ctx_get_error_depth (MonoBtlsX509StoreCtx *ctx)
94 return X509_STORE_CTX_get_error_depth (ctx->ctx);
97 MONO_API MonoBtlsX509Chain *
98 mono_btls_x509_store_ctx_get_chain (MonoBtlsX509StoreCtx *ctx)
100 STACK_OF(X509) *certs;
102 certs = X509_STORE_CTX_get_chain (ctx->ctx);
103 if (!certs)
104 return NULL;
106 return mono_btls_x509_chain_from_certs (certs);
109 MONO_API MonoBtlsX509Chain *
110 mono_btls_x509_store_ctx_get_untrusted (MonoBtlsX509StoreCtx *ctx)
112 STACK_OF(X509) *untrusted;
115 * Unfortunately, there is no accessor function for this.
117 * This is the set of certificate that's passed in by
118 * X509_STORE_CTX_init() and X509_STORE_CTX_set_chain().
120 untrusted = ctx->ctx->untrusted;
121 if (!untrusted)
122 return NULL;
124 return mono_btls_x509_chain_from_certs (untrusted);
127 MONO_API int
128 mono_btls_x509_store_ctx_init (MonoBtlsX509StoreCtx *ctx,
129 MonoBtlsX509Store *store, MonoBtlsX509Chain *chain)
131 STACK_OF(X509) *certs;
132 X509 *leaf;
133 int ret;
135 if (ctx->store)
136 return 0;
138 certs = mono_btls_x509_chain_peek_certs (chain);
139 if (!certs || !sk_X509_num (certs))
140 return 0;
142 ctx->store = mono_btls_x509_store_up_ref(store);
143 ctx->chain = mono_btls_x509_chain_up_ref(chain);
145 leaf = sk_X509_value (certs, 0);
146 ret = X509_STORE_CTX_init (ctx->ctx, mono_btls_x509_store_peek_store (store), leaf, certs);
147 if (ret != 1)
148 return ret;
150 X509_STORE_CTX_set_app_data (ctx->ctx, ctx);
151 return 1;
154 MONO_API int
155 mono_btls_x509_store_ctx_set_param (MonoBtlsX509StoreCtx *ctx, MonoBtlsX509VerifyParam *param)
157 return X509_VERIFY_PARAM_set1 (X509_STORE_CTX_get0_param (ctx->ctx), mono_btls_x509_verify_param_peek_param (param));
160 MONO_API int
161 mono_btls_x509_store_ctx_verify_cert (MonoBtlsX509StoreCtx *ctx)
163 return X509_verify_cert (ctx->ctx);
166 MONO_API X509 *
167 mono_btls_x509_store_ctx_get_by_subject (MonoBtlsX509StoreCtx *ctx, MonoBtlsX509Name *name)
169 X509_OBJECT obj;
170 X509 *x509;
171 int ret;
173 ret = X509_STORE_get_by_subject (ctx->ctx, X509_LU_X509, mono_btls_x509_name_peek_name (name), &obj);
174 if (ret != X509_LU_X509) {
175 X509_OBJECT_free_contents (&obj);
176 return NULL;
179 x509 = X509_up_ref (obj.data.x509);
180 return x509;
183 MONO_API X509 *
184 mono_btls_x509_store_ctx_get_current_cert (MonoBtlsX509StoreCtx *ctx)
186 X509 *x509 = X509_STORE_CTX_get_current_cert (ctx->ctx);
187 if (!x509)
188 return NULL;
189 return X509_up_ref (x509);
192 MONO_API X509 *
193 mono_btls_x509_store_ctx_get_current_issuer (MonoBtlsX509StoreCtx *ctx)
195 X509 *x509 = X509_STORE_CTX_get0_current_issuer (ctx->ctx);
196 if (!x509)
197 return NULL;
198 return X509_up_ref (x509);
201 MONO_API MonoBtlsX509VerifyParam *
202 mono_btls_x509_store_ctx_get_verify_param (MonoBtlsX509StoreCtx *ctx)
204 X509_VERIFY_PARAM *param;
206 param = X509_STORE_CTX_get0_param (ctx->ctx);
207 if (!param)
208 return NULL;
210 return mono_btls_x509_verify_param_from_store_ctx (ctx, param);
213 MONO_API int
214 mono_btls_x509_store_ctx_get_foo (MonoBtlsX509StoreCtx *ctx)
216 return 0;