-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathtls_common_lib.cpp
More file actions
164 lines (131 loc) · 4.04 KB
/
tls_common_lib.cpp
File metadata and controls
164 lines (131 loc) · 4.04 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
#include "tls_common_lib.h"
// Verify callback.
static int _verify_callback(int preverify, X509_STORE_CTX *x509_ctx){
return preverify;
}
// Initialize OpenSSL by loading all error strings and algorithms.
void init_openssl()
{
SSL_library_init();
SSL_load_error_strings();
OpenSSL_add_all_algorithms();
}
// Clean up OpenSSL
void cleanup_openssl()
{
EVP_cleanup();
}
// Create an OpenSSL Context
// Create an OpenSSL Context
// CACertName is the filename of the CA's certificate. Needed only if
// verifyPeer is set to true.
// Set verifyPeer to true to verify the other side
// isServer = 0 to create context for a client, and 1 to create context for a server
SSL_CTX *create_context(const char *CACertName, int verifyPeer, int isServer)
{
// Create an SSL context
const SSL_METHOD *method;
SSL_CTX *ctx;
// To maintain compatibility we will continue to
// use SSLv23, but will restrict the use
// of SSLv2 and SSLv3 which are known to have
// security flaws.
if(!isServer){
method = SSLv23_client_method();
}
else {
method = SSLv23_server_method();
}
ctx = SSL_CTX_new(method);
if(!ctx)
{
perror("Unable to create SSL context: ");
ERR_print_errors_fp(stderr);
exit(-1);
}
// Here is where we restrict the use of SSLv2 and SSLv3
SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
if(verifyPeer) {
// Turn on verification of certificate
SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, _verify_callback);
// Set verification depth
SSL_CTX_set_verify_depth(ctx, 4);
// We load in the CA certificate to verify the server's certificate
SSL_CTX_load_verify_locations(ctx, CACertName, NULL);
}
return ctx;
}
// Configure the OpenSSL Context.
// ctx - Context createde in create_context
// cert_name - Filename of your certificate (.crt or .pem) file
// pkey_name - Filename of your private key (.key) file
void configure_context(SSL_CTX *ctx, const char *cert_name, const char *pkey_name)
{
// Use elliptic curve diffie-helman to exchange keys
SSL_CTX_set_ecdh_auto(ctx, 1);
// Load our server certificate
if(SSL_CTX_use_certificate_file(ctx, cert_name, SSL_FILETYPE_PEM) <= 0)
{
ERR_print_errors_fp(stderr);
exit(-1);
}
// Load our server private key
if(SSL_CTX_use_PrivateKey_file(ctx, pkey_name, SSL_FILETYPE_PEM) <= 0)
{
ERR_print_errors_fp(stderr);
exit(-1);
}
}
//
// This function prints out the server's certificate details of the SSL session.
// ssl = SSL session
void printCertificate(SSL *ssl)
{
// NEW: Getting certificates
X509 *cert=NULL;
X509_NAME *certname = NULL;
cert = SSL_get_peer_certificate(ssl);
if(cert == NULL)
{
printf( "Cannot get peer certificate\n");
return;
}
certname = X509_NAME_new();
certname = X509_get_subject_name(cert);
X509_NAME_print_ex_fp(stdout, certname, 0, 0);
printf( "\n\n");
}
// This function verifies the certificate. Returns TRUE if
// the certificate is valid
int verifyCertificate(SSL *ssl)
{
long res = SSL_get_verify_result(ssl);
return (res == X509_V_OK);
}
// Enables host verification
long setHostVerification(SSL *ssl, const char *hostname)
{
X509_VERIFY_PARAM *param = SSL_get0_param(ssl);
X509_VERIFY_PARAM_set_hostflags(param, X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS);
long res = X509_VERIFY_PARAM_set1_host(param, hostname, strlen(hostname));
return res;
}
// Write to the SSL connection. Called from within
// the worker thread. Returns the number of
// bytes actually written. If <0 an error has occurred.
// Call perror to print the error
// If 0 the connection has been closed.
int sslWrite(void *conn, const char *buffer, int len) {
SSL *ssl = (SSL *) conn;
return SSL_write(ssl, buffer, len);
}
// Read from SSL connection. Called from within
// the worker thread. Returns the number of
// bytes actually read. If <0 an error has occurred.
// Call perror to print the error
// If 0 the connection has been closed.
// Read data is written into buffer.
int sslRead(void *conn, char *buffer, int len) {
SSL *ssl = (SSL *) conn;
return SSL_read(ssl, buffer, len);
}