TLS Server with Channel ID by BoringSSL
#include <openssl/ssl.h> | |
#include <stdio.h> | |
#include <sys/types.h> | |
#include <sys/socket.h> | |
#include <netinet/in.h> | |
#define CERTFILE "/home/ohtsu/tmp/cert/bundle.crt" | |
#define KEYFILE "/home/ohtsu/tmp/cert/server.key" | |
#define CIPHERLIST "ECDHE-RSA-AES128-GCM-SHA256" | |
#define CURVENAME "prime256v1" | |
#define PORT 8443 | |
void ssl_loop(SSL_CTX *ctx, int sock) { | |
SSL *ssl; | |
int r,i; | |
char buf[64]; | |
unsigned char channel_id[64]; | |
ssl = SSL_new(ctx); | |
SSL_set_fd(ssl, sock); | |
/* サーバでのChannel IDを有効にする */ | |
SSL_enable_tls_channel_id(ssl); | |
SSL_accept(ssl); | |
/* TLS Handshake後にクライアントからのChannel IDを取得する */ | |
r = SSL_get_tls_channel_id(ssl, channel_id, sizeof(channel_id)); | |
if (r > 0) { | |
/* 64byteのChannel IDをHexで出力 */ | |
fprintf(stderr, "channel_id="); | |
for(i=0; i < r; i++) { | |
fprintf(stderr, "%X",channel_id[i]); | |
} | |
fprintf(stderr, "\n"); | |
} else { | |
fprintf(stderr, "** No channel_id **\n"); | |
} | |
for(;;) { | |
r = SSL_read(ssl, buf, sizeof(buf)); | |
if (r <= 0) break; | |
fwrite(buf, 1, r, stdout); | |
} | |
fprintf(stderr, "SSL connection to be shutdowned.\n"); | |
SSL_set_shutdown(ssl, SSL_SENT_SHUTDOWN); | |
SSL_shutdown(ssl); | |
SSL_free(ssl); | |
} | |
int main(int argc, char* argv[]) { | |
int r, server; | |
int sock, len, opt = 1; | |
SSL_CTX *ctx; | |
EC_KEY* ecdh; | |
struct sockaddr_in addr, client; | |
SSL_library_init(); | |
SSL_load_error_strings(); | |
ctx = SSL_CTX_new(SSLv23_method()); | |
r = SSL_CTX_use_certificate_chain_file(ctx, CERTFILE); | |
r = SSL_CTX_use_PrivateKey_file(ctx, KEYFILE, SSL_FILETYPE_PEM); | |
SSL_CTX_set_options(ctx, SSL_OP_SINGLE_ECDH_USE); | |
SSL_CTX_set_cipher_list(ctx, CIPHERLIST); | |
ecdh = EC_KEY_new_by_curve_name(OBJ_sn2nid(CURVENAME)); | |
SSL_CTX_set_tmp_ecdh(ctx, ecdh); | |
addr.sin_family = AF_INET; | |
addr.sin_port = htons(PORT); | |
addr.sin_addr.s_addr = INADDR_ANY; | |
server = socket(AF_INET, SOCK_STREAM, 0); | |
setsockopt(server, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); | |
bind(server,(struct sockaddr *)&addr, sizeof(addr)); | |
listen(server, 5); | |
for(;;) { | |
len = sizeof(client); | |
sock = accept(server, (struct sockaddr *)&client, &len); | |
ssl_loop(ctx, sock); | |
} | |
close(sock); | |
SSL_CTX_free(ctx); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment