1 #include "ssl_internal.h" |
|
2 |
|
3 #include <assert.h> |
|
4 |
|
5 /* |
|
6 * Global shared anonymous client credentials |
|
7 */ |
|
8 struct ssl_client_cred ssl_client_cred_anon = { .x509 = NULL, .verify = false, .refcount = 0 }; |
|
9 |
|
10 |
|
11 // XXX: GnuTLS log func |
|
12 void _log (int level, const char *msg) |
|
13 { |
|
14 printf("gnutls: %d: %s", level, msg); |
|
15 } |
|
16 |
|
17 err_t ssl_global_init (error_t *err) |
|
18 { |
|
19 // global init |
|
20 if ((ERROR_EXTRA(err) = gnutls_global_init()) < 0) |
|
21 return SET_ERROR(err, ERR_GNUTLS_GLOBAL_INIT); |
|
22 |
|
23 // initialize the anon client credentials |
|
24 if ((ERROR_EXTRA(err) = gnutls_certificate_allocate_credentials(&ssl_client_cred_anon.x509)) < 0) |
|
25 return SET_ERROR(err, ERR_GNUTLS_CERT_ALLOC_CRED); |
|
26 |
|
27 // XXX: debug |
|
28 // gnutls_global_set_log_function(&_log); |
|
29 // gnutls_global_set_log_level(11); |
|
30 |
|
31 // done |
|
32 return SUCCESS; |
|
33 } |
|
34 |
|
35 static void ssl_client_cred_destroy (struct ssl_client_cred *cred) |
|
36 { |
|
37 // simple |
|
38 gnutls_certificate_free_credentials(cred->x509); |
|
39 |
|
40 free(cred); |
|
41 } |
|
42 |
|
43 err_t ssl_client_cred_create (struct ssl_client_cred **ctx_cred, |
|
44 const char *cafile_path, bool verify, |
|
45 const char *cert_path, const char *pkey_path, |
|
46 error_t *err |
|
47 ) { |
|
48 struct ssl_client_cred *cred; |
|
49 |
|
50 // alloc it |
|
51 if ((cred = calloc(1, sizeof(*cred))) == NULL) |
|
52 return SET_ERROR(err, ERR_CALLOC); |
|
53 |
|
54 // create the cert |
|
55 if ((ERROR_EXTRA(err) = gnutls_certificate_allocate_credentials(&cred->x509)) < 0) |
|
56 JUMP_SET_ERROR(err, ERR_GNUTLS_CERT_ALLOC_CRED); |
|
57 |
|
58 // load the trusted ca certs? |
|
59 if (cafile_path) { |
|
60 // load them |
|
61 if ((ERROR_EXTRA(err) = gnutls_certificate_set_x509_trust_file(cred->x509, cafile_path, GNUTLS_X509_FMT_PEM)) < 0) |
|
62 JUMP_SET_ERROR(err, ERR_GNUTLS_CERT_SET_X509_TRUST_FILE); |
|
63 |
|
64 } |
|
65 |
|
66 // set the verify flags? |
|
67 cred->verify = verify; |
|
68 gnutls_certificate_set_verify_flags(cred->x509, 0); |
|
69 |
|
70 // load the client cert? |
|
71 if (cert_path || pkey_path) { |
|
72 // need both... |
|
73 assert(cert_path && pkey_path); |
|
74 |
|
75 // load |
|
76 if ((ERROR_EXTRA(err) = gnutls_certificate_set_x509_key_file(cred->x509, cert_path, pkey_path, GNUTLS_X509_FMT_PEM))) |
|
77 JUMP_SET_ERROR(err, ERR_GNUTLS_CERT_SET_X509_KEY_FILE); |
|
78 } |
|
79 |
|
80 // ok |
|
81 cred->refcount = 1; |
|
82 *ctx_cred = cred; |
|
83 |
|
84 return SUCCESS; |
|
85 |
|
86 error: |
|
87 // release |
|
88 ssl_client_cred_destroy(cred); |
|
89 |
|
90 return ERROR_CODE(err); |
|
91 } |
|
92 |
|
93 void ssl_client_cred_get (struct ssl_client_cred *cred) |
|
94 { |
|
95 cred->refcount++; |
|
96 } |
|
97 |
|
98 void ssl_client_cred_put (struct ssl_client_cred *cred) |
|
99 { |
|
100 if (--cred->refcount == 0) |
|
101 ssl_client_cred_destroy(cred); |
|
102 } |
|