Merge pull request #5714 from alexischr/update_bockbuild
[mono.git] / mono / btls / btls-pkcs12.c
1 //
2 //  btls-pkcs12.c
3 //  MonoBtls
4 //
5 //  Created by Martin Baulig on 3/8/16.
6 //  Copyright © 2016 Xamarin. All rights reserved.
7 //
8
9 #include <btls-pkcs12.h>
10 #include <openssl/pkcs12.h>
11
12 struct MonoBtlsPkcs12 {
13         STACK_OF(X509) *certs;
14         EVP_PKEY *private_key;
15         CRYPTO_refcount_t references;
16 };
17
18 MONO_API MonoBtlsPkcs12 *
19 mono_btls_pkcs12_new (void)
20 {
21         MonoBtlsPkcs12 *pkcs12 = (MonoBtlsPkcs12 *)OPENSSL_malloc (sizeof (MonoBtlsPkcs12));
22         if (pkcs12 == NULL)
23                 return NULL;
24
25         memset (pkcs12, 0, sizeof(MonoBtlsPkcs12));
26         pkcs12->certs = sk_X509_new_null ();
27         pkcs12->references = 1;
28         return pkcs12;
29 }
30
31 MONO_API int
32 mono_btls_pkcs12_get_count (MonoBtlsPkcs12 *pkcs12)
33 {
34         return (int)sk_X509_num (pkcs12->certs);
35 }
36
37 MONO_API X509 *
38 mono_btls_pkcs12_get_cert (MonoBtlsPkcs12 *pkcs12, int index)
39 {
40         X509 *cert;
41
42         if ((size_t)index >= sk_X509_num (pkcs12->certs))
43                 return NULL;
44         cert = sk_X509_value (pkcs12->certs, index);
45         if (cert)
46                 X509_up_ref (cert);
47         return cert;
48 }
49
50 MONO_API STACK_OF(X509) *
51 mono_btls_pkcs12_get_certs (MonoBtlsPkcs12 *pkcs12)
52 {
53         return pkcs12->certs;
54 }
55
56 MONO_API int
57 mono_btls_pkcs12_free (MonoBtlsPkcs12 *pkcs12)
58 {
59         if (!CRYPTO_refcount_dec_and_test_zero (&pkcs12->references))
60                 return 0;
61
62         sk_X509_pop_free (pkcs12->certs, X509_free);
63         OPENSSL_free (pkcs12);
64         return 1;
65 }
66
67 MONO_API MonoBtlsPkcs12 *
68 mono_btls_pkcs12_up_ref (MonoBtlsPkcs12 *pkcs12)
69 {
70         CRYPTO_refcount_inc (&pkcs12->references);
71         return pkcs12;
72 }
73
74 MONO_API void
75 mono_btls_pkcs12_add_cert (MonoBtlsPkcs12 *pkcs12, X509 *x509)
76 {
77         X509_up_ref (x509);
78         sk_X509_push (pkcs12->certs, x509);
79 }
80
81 MONO_API int
82 mono_btls_pkcs12_import (MonoBtlsPkcs12 *pkcs12, const void *data, int len, const void *password)
83 {
84         CBS cbs;
85         CBS_init (&cbs, data, len);
86         return PKCS12_get_key_and_certs (&pkcs12->private_key, pkcs12->certs, &cbs, password);
87 }
88
89 MONO_API int
90 mono_btls_pkcs12_has_private_key (MonoBtlsPkcs12 *pkcs12)
91 {
92         return pkcs12->private_key != NULL;
93 }
94
95 MONO_API EVP_PKEY *
96 mono_btls_pkcs12_get_private_key (MonoBtlsPkcs12 *pkcs12)
97 {
98         if (!pkcs12->private_key)
99                 return NULL;
100         return EVP_PKEY_up_ref (pkcs12->private_key);
101 }