conn: support openssl
[pop3.git] / conn_openssl.c
blob05c5f991a74dc319e8cafcd49a9bee6f89838ed3
1 #include <arpa/inet.h>
2 #include <netinet/in.h>
3 #include <netdb.h>
4 #include <signal.h>
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <string.h>
8 #include <sys/socket.h>
9 #include <sys/stat.h>
10 #include <sys/types.h>
11 #include <time.h>
12 #include <unistd.h>
14 #include <openssl/crypto.h>
15 #include <openssl/x509.h>
16 #include <openssl/pem.h>
17 #include <openssl/ssl.h>
18 #include <openssl/err.h>
20 struct conn {
21 int fd;
22 SSL_CTX *ctx;
23 SSL *ssl;
26 int conn_read(struct conn *conn, char *buf, int len)
28 return SSL_read(conn->ssl, buf, sizeof(buf) - 1);
31 int conn_write(struct conn *conn, char *buf, int len)
33 return SSL_write(conn->ssl, buf, len);
36 static int conns_init(struct conn *conn, char *certfile)
38 SSLeay_add_ssl_algorithms();
39 SSL_load_error_strings();
40 conn->ctx = SSL_CTX_new(SSLv23_method());
41 if (!conn->ctx)
42 return 1;
43 conn->ssl = SSL_new(conn->ctx);
44 if (!conn->ssl)
45 return 1;
46 if (certfile) {
47 SSL_CTX_set_verify(conn->ctx, SSL_VERIFY_PEER, NULL);
48 SSL_CTX_load_verify_locations(conn->ctx, certfile, NULL);
50 SSL_set_fd(conn->ssl, conn->fd);
51 if (SSL_connect(conn->ssl) != 1)
52 return 1;
53 if (SSL_get_verify_result(conn->ssl) != X509_V_OK)
54 return 1;
55 return 0;
58 struct conn *conn_connect(char *addr, char *port, char *certfile)
60 struct addrinfo hints, *addrinfo;
61 struct conn *conn;
62 int fd;
64 memset(&hints, 0, sizeof(hints));
65 hints.ai_family = AF_UNSPEC;
66 hints.ai_socktype = SOCK_STREAM;
67 hints.ai_flags = AI_PASSIVE;
69 if (getaddrinfo(addr, port, &hints, &addrinfo))
70 return NULL;
71 fd = socket(addrinfo->ai_family, addrinfo->ai_socktype,
72 addrinfo->ai_protocol);
74 if (connect(fd, addrinfo->ai_addr, addrinfo->ai_addrlen) == -1) {
75 close(fd);
76 freeaddrinfo(addrinfo);
77 return NULL;
79 freeaddrinfo(addrinfo);
81 conn = malloc(sizeof(*conn));
82 memset(conn, 0, sizeof(*conn));
83 conn->fd = fd;
84 if (conns_init(conn, certfile)) {
85 free(conn);
86 return NULL;
88 return conn;
91 int conn_close(struct conn *conn)
93 SSL_shutdown(conn->ssl);
94 SSL_free(conn->ssl);
95 SSL_CTX_free(conn->ctx);
96 close(conn->fd);
97 free(conn);
98 return 0;