-
Notifications
You must be signed in to change notification settings - Fork 0
/
ssl.c
93 lines (76 loc) · 1.99 KB
/
ssl.c
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
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <strings.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include "ssl.h"
// N for listen(FD, N)
const int lq = 12;
// Close the ssl file descriptor
void close_ssl(SSL *ssl) {
int fd = SSL_get_fd(ssl);
SSL_free(ssl);
close(fd);
}
// Initializes OpenSSL and returns an SSL context
SSL_CTX* init_ctx() {
// Load crypto suite and error messages
OpenSSL_add_all_algorithms();
SSL_load_error_strings();
// Determine the SSL method
const SSL_METHOD *method = TLS_server_method();
// Initialize the context
SSL_CTX *ctx = SSL_CTX_new(method);
if (ctx == NULL) {
ERR_print_errors_fp(stderr);
abort();
}
return ctx;
}
// Loads a certificate and private key
void load_cert(SSL_CTX *ctx, char *cert, char *key) {
// Load certificate
if (SSL_CTX_use_certificate_file(ctx, cert, SSL_FILETYPE_PEM) <= 0) {
ERR_print_errors_fp(stderr);
abort();
}
// Load private key
if (SSL_CTX_use_PrivateKey_file(ctx, key, SSL_FILETYPE_PEM) <= 0 ) {
ERR_print_errors_fp(stderr);
abort();
}
// Validate private key
if (!SSL_CTX_check_private_key(ctx)) {
fprintf(stderr, "Error: Private key does not match the public certificate\n");
abort();
}
}
// Takes the port to bind to and returns the file descriptor of a newly initialized socket
int init_fd(int port) {
// Create socket
int fd, on = 1;
if ((fd = socket(PF_INET, SOCK_STREAM, 0)) == 0) {
fprintf(stderr, "Error: Failed to create socket");
return 0;
}
setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
// Bind port
struct sockaddr_in addr;
bzero(&addr, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = INADDR_ANY;
if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
perror("Error: Failed to bind port");
abort();
}
// Configure
if (listen(fd, lq) < 0) {
fprintf(stderr, "Error: Failed to configure listening port");
abort();
}
return fd;
}