blob: 8746eca4af1acbba9ae3387c115106899a640e36 [file] [log] [blame]
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001// Copyright (C) 2010 David Sugar, Tycho Softworks.
2//
3// This file is part of GNU uCommon C++.
4//
5// GNU uCommon C++ is free software: you can redistribute it and/or modify
6// it under the terms of the GNU Lesser General Public License as published
7// by the Free Software Foundation, either version 3 of the License, or
8// (at your option) any later version.
9//
10// GNU uCommon C++ is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU Lesser General Public License for more details.
14//
15// You should have received a copy of the GNU Lesser General Public License
16// along with GNU uCommon C++. If not, see <http://www.gnu.org/licenses/>.
17
18#include "local.h"
19
20extern "C" {
21 static void secure_shutdown(void)
22 {
23 gnutls_global_deinit();
24 }
25}
26
27gnutls_priority_t context::priority_cache;
28
29bool secure::fips(void)
30{
31 return false;
32}
33
34bool secure::init(void)
35{
36 static bool initialized = false;
37
38 if(!initialized) {
39 Thread::init();
40 Socket::init();
41
42 gnutls_global_init();
43 gnutls_priority_init (&context::priority_cache, "NORMAL", NULL);
44 atexit(secure_shutdown);
45 initialized = true;
46 }
47 return true;
48}
49
50secure::server_t secure::server(const char *certfile, const char *ca)
51{
52 context *ctx = new context;
53
54 if(!ctx)
55 return NULL;
56
57 ctx->error = secure::OK;
58 ctx->connect = GNUTLS_SERVER;
59 ctx->xtype = GNUTLS_CRD_CERTIFICATE;
60 ctx->xcred = NULL;
61 ctx->dh = NULL;
62 gnutls_certificate_allocate_credentials(&ctx->xcred);
63
64 gnutls_certificate_set_x509_key_file(ctx->xcred, certfile, certfile, GNUTLS_X509_FMT_PEM);
65
66 if(!ca)
67 return ctx;
68
69 if(eq(ca, "*"))
70 ca = oscerts();
71
72 gnutls_certificate_set_x509_trust_file (ctx->xcred, ca, GNUTLS_X509_FMT_PEM);
73
74 return ctx;
75}
76
77secure::client_t secure::client(const char *ca)
78{
79 context *ctx = new context;
80
81 if(!ctx)
82 return NULL;
83
84 ctx->error = secure::OK;
85 ctx->connect = GNUTLS_CLIENT;
86 ctx->xtype = GNUTLS_CRD_CERTIFICATE;
87 ctx->xcred = NULL;
88 ctx->dh = NULL;
89 gnutls_certificate_allocate_credentials(&ctx->xcred);
90
91 if(!ca)
92 return ctx;
93
94 if(eq(ca, "*"))
95 ca = oscerts();
96
97 gnutls_certificate_set_x509_trust_file (ctx->xcred, ca, GNUTLS_X509_FMT_PEM);
98
99 return ctx;
100}
101
102context::~context()
103{
104 if(dh)
105 gnutls_dh_params_deinit(dh);
106
107 if(!xcred)
108 return;
109
110 switch(xtype) {
111 case GNUTLS_CRD_ANON:
112 gnutls_anon_free_client_credentials((gnutls_anon_client_credentials_t)xcred);
113 break;
114 case GNUTLS_CRD_CERTIFICATE:
115 gnutls_certificate_free_credentials(xcred);
116 break;
117 default:
118 break;
119 }
120}
121
122secure::~secure()
123{
124}
125
126gnutls_session_t context::session(context *ctx)
127{
128 SSL ssl = NULL;
129 if(ctx && ctx->xcred && ctx->err() == secure::OK) {
130 gnutls_init(&ssl, ctx->connect);
131 switch(ctx->connect) {
132 case GNUTLS_CLIENT:
133 gnutls_priority_set_direct(ssl, "PERFORMANCE", NULL);
134 break;
135 case GNUTLS_SERVER:
136 gnutls_priority_set(ssl, context::priority_cache);
137 gnutls_certificate_server_set_request(ssl, GNUTLS_CERT_REQUEST);
138 gnutls_session_enable_compatibility_mode(ssl);
139 default:
140 break;
141 }
142 gnutls_credentials_set(ssl, ctx->xtype, ctx->xcred);
143 }
144 return ssl;
145}
146
147