MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
yassl.cpp
1 /*
2  Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
3 
4  This program is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation; version 2 of the License.
7 
8  This program is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  GNU General Public License for more details.
12 
13  You should have received a copy of the GNU General Public License
14  along with this program; see the file COPYING. If not, write to the
15  Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
16  MA 02110-1301 USA.
17 */
18 
19 
20 /* yaSSL implements external API
21  */
22 
23 #include "runtime.hpp"
24 #include "yassl.hpp"
25 #include "yassl_int.hpp"
26 #include "handshake.hpp"
27 #include <stdio.h>
28 
29 #include "openssl/ssl.h" // get rid of this
30 
31 
32 
33 namespace yaSSL {
34 
35 
36 
37 struct Base {
38  SSL_METHOD* method_;
39  SSL_CTX* ctx_;
40  SSL* ssl_;
41 
42  char* ca_;
43  char* cert_;
44  char* key_;
45 
46  DH* dh_;
47 
48  Base() : method_(0), ctx_(0), ssl_(0), ca_(0), cert_(0), key_(0), dh_(0)
49  {}
50 
51  ~Base()
52  {
53  if (dh_) DH_free(dh_);
54  delete[] key_;
55  delete[] cert_;
56  delete[] ca_;
57  SSL_CTX_free(ctx_); // frees method_ too
58  SSL_free(ssl_);
59  }
60 };
61 
62 
63 void SetDH(Base&);
64 
65 void SetUpBase(Base& base, ConnectionEnd end, SOCKET_T s)
66 {
67  base.method_ = new SSL_METHOD(end, ProtocolVersion(3,1));
68  base.ctx_ = new SSL_CTX(base.method_);
69 
70  if (base.ca_)
71  if (SSL_CTX_load_verify_locations(base.ctx_,
72  base.ca_, 0) != SSL_SUCCESS) throw(0);
73  if (base.cert_)
74  if (SSL_CTX_use_certificate_file(base.ctx_,
75  base.cert_, SSL_FILETYPE_PEM) != SSL_SUCCESS) throw(0);
76  if (base.key_)
77  if (SSL_CTX_use_PrivateKey_file(base.ctx_, base.key_,
78  SSL_FILETYPE_PEM) != SSL_SUCCESS) throw(0);
79 
80  if (end == server_end) SetDH(base);
81 
82  base.ssl_ = new SSL(base.ctx_);
83  base.ssl_->useSocket().set_fd(s);
84 }
85 
86 
87 void SetDH(Base& base)
88 {
89  static unsigned char dh512_p[] =
90  {
91  0xDA,0x58,0x3C,0x16,0xD9,0x85,0x22,0x89,0xD0,0xE4,0xAF,0x75,
92  0x6F,0x4C,0xCA,0x92,0xDD,0x4B,0xE5,0x33,0xB8,0x04,0xFB,0x0F,
93  0xED,0x94,0xEF,0x9C,0x8A,0x44,0x03,0xED,0x57,0x46,0x50,0xD3,
94  0x69,0x99,0xDB,0x29,0xD7,0x76,0x27,0x6B,0xA2,0xD3,0xD4,0x12,
95  0xE2,0x18,0xF4,0xDD,0x1E,0x08,0x4C,0xF6,0xD8,0x00,0x3E,0x7C,
96  0x47,0x74,0xE8,0x33,
97  };
98 
99  static unsigned char dh512_g[] =
100  {
101  0x02,
102  };
103 
104  if ( (base.dh_ = DH_new()) ) {
105  base.dh_->p = BN_bin2bn(dh512_p, sizeof(dh512_p), 0);
106  base.dh_->g = BN_bin2bn(dh512_g, sizeof(dh512_g), 0);
107  }
108  if (!base.dh_->p || !base.dh_->g) {
109  DH_free(base.dh_);
110  base.dh_ = 0;
111  }
112  SSL_CTX_set_tmp_dh(base.ctx_, base.dh_);
113 }
114 
115 
116 void NewCopy(char*& dst, const char* src)
117 {
118  size_t len = strlen(src) + 1;
119  dst = new char[len];
120 
121  strncpy(dst, src, len);
122 }
123 
124 
125 // Client Implementation
127  Base base_;
128 };
129 
130 
131 Client::Client() : pimpl_(new ClientImpl)
132 {}
133 
134 
135 Client::~Client() { delete pimpl_; }
136 
137 
138 int Client::Connect(SOCKET_T s)
139 {
140  SetUpBase(pimpl_->base_, client_end, s);
141  return SSL_connect(pimpl_->base_.ssl_);
142 }
143 
144 
145 int Client::Write(const void* buffer, int sz)
146 {
147  return sendData(*pimpl_->base_.ssl_, buffer, sz);
148 }
149 
150 
151 int Client::Read(void* buffer, int sz)
152 {
153  Data data(min(sz, MAX_RECORD_SIZE), static_cast<opaque*>(buffer));
154  return receiveData(*pimpl_->base_.ssl_, data);
155 }
156 
157 
158 void Client::SetCA(const char* name)
159 {
160  NewCopy(pimpl_->base_.ca_, name);
161 }
162 
163 
164 void Client::SetCert(const char* name)
165 {
166  NewCopy(pimpl_->base_.cert_, name);
167 }
168 
169 
170 void Client::SetKey(const char* name)
171 {
172  NewCopy(pimpl_->base_.key_, name);
173 }
174 
175 
176 
177 // Server Implementation
179  Base base_;
180 };
181 
182 
183 Server::Server() : pimpl_(new ServerImpl)
184 {}
185 
186 
187 Server::~Server() { delete pimpl_; }
188 
189 
190 int Server::Accept(SOCKET_T s)
191 {
192  SetUpBase(pimpl_->base_, server_end, s);
193  return SSL_accept(pimpl_->base_.ssl_);
194 }
195 
196 
197 int Server::Write(const void* buffer, int sz)
198 {
199  return sendData(*pimpl_->base_.ssl_, buffer, sz);
200 }
201 
202 
203 int Server::Read(void* buffer, int sz)
204 {
205  Data data(min(sz, MAX_RECORD_SIZE), static_cast<opaque*>(buffer));
206  return receiveData(*pimpl_->base_.ssl_, data);
207 }
208 
209 
210 void Server::SetCA(const char* name)
211 {
212  NewCopy(pimpl_->base_.ca_, name);
213 }
214 
215 
216 void Server::SetCert(const char* name)
217 {
218  NewCopy(pimpl_->base_.cert_, name);
219 }
220 
221 
222 void Server::SetKey(const char* name)
223 {
224  NewCopy(pimpl_->base_.key_, name);
225 }
226 
227 
228 
229 } // namespace yaSSL