Skip to content

Instantly share code, notes, and snippets.

@kinichiro
Last active October 2, 2023 14:56
Show Gist options
  • Save kinichiro/9ac1f6768d490bb3d9828e9ffac7d098 to your computer and use it in GitHub Desktop.
Save kinichiro/9ac1f6768d490bb3d9828e9ffac7d098 to your computer and use it in GitHub Desktop.
Hello libtls - libressl libtls API sample program
Hello libtls - libressl libtls API sample program
/* libtls_client.c */
#include <stdio.h>
#include <string.h>
#include <err.h>
#include <tls.h>
int
main(int argc, char *argv[])
{
struct tls_config *cfg = NULL;
struct tls *ctx = NULL;
uint8_t *mem;
size_t mem_len;
ssize_t writelen;
unsigned char buf[BUFSIZ] = "Hello libtls.";
/*
** initialize libtls
*/
if (tls_init() != 0)
err(1, "tls_init:");
/*
** configure libtls
*/
if ((cfg = tls_config_new()) == NULL)
err(1, "tls_config_new:");
/* set root certificate (CA) */
if (tls_config_set_ca_file(cfg, "test_ca.pem") != 0)
err(1, "tls_config_set_ca_file:");
/*
** initiate client context
*/
if ((ctx = tls_client()) == NULL)
err(1, "tls_client:");
/*
** apply config to context
*/
if (tls_configure(ctx, cfg) != 0)
err(1, "tls_configure: %s", tls_error(ctx));
/*
** connect to server
*/
if (tls_connect(ctx, "localhost.test_dummy.com", "12345") != 0)
err(1, "tls_connect: %s", tls_error(ctx));
/*
** send message to server
*/
if((writelen = tls_write(ctx, buf, strlen(buf))) < 0)
err(1, "tls_write: %s", tls_error(ctx));
printf("sent message: [%*.*s]\n", writelen, writelen, buf);
/*
** dump session informations
*/
dump_session_info(ctx, "localhost.test_dummy.com");
/*
** clean up all
*/
if (tls_close(ctx) != 0)
err(1, "tls_close: %s", tls_error(ctx));
tls_free(ctx);
tls_config_free(cfg);
return(0);
}
/* libtls_server.c */
#include <stdio.h>
#include <errno.h>
#include <err.h>
#include <tls.h>
int
main(int argc, char *argv[])
{
struct tls_config *cfg = NULL;
struct tls *ctx = NULL, *cctx = NULL;
uint8_t *mem;
size_t mem_len;
int clfd;
ssize_t readlen;
unsigned char buf[BUFSIZ];
/*
** initialize libtls
*/
if (tls_init() != 0)
err(1, "tls_init:");
/*
** configure libtls
*/
if ((cfg = tls_config_new()) == NULL)
err(1, "tls_config_new:");
/* set root certificate (CA) */
if ((mem = tls_load_file("test_ca.pem", &mem_len, NULL)) == NULL)
err(1, "tls_load_file(ca):");
if (tls_config_set_ca_mem(cfg, mem, mem_len) != 0)
err(1, "tls_config_set_ca_mem:");
/* set server certificate */
if ((mem = tls_load_file("test_server_cert.pem", &mem_len, NULL)) == NULL)
err(1, "tls_load_file(server):");
if (tls_config_set_cert_mem(cfg, mem, mem_len) != 0)
err(1, "tls_config_set_cert_mem:");
/* set server private key */
if ((mem = tls_load_file("test_server_key.pem", &mem_len, "test-server-pass")) == NULL)
err(1, "tls_load_file(serverkey):");
if (tls_config_set_key_mem(cfg, mem, mem_len) != 0)
err(1, "tls_config_set_key_mem:");
/*
** initiate server context
*/
if ((ctx = tls_server()) == NULL)
err(1, "tls_server:");
/*
** apply config to context
*/
if (tls_configure(ctx, cfg) != 0)
err(1, "tls_configure: %s", tls_error(ctx));
/*
** create and accept socket
*/
printf("setting up socket ...\n");
if ((clfd = setup_socket(12345)) < 0)
err(1, "setup_socket: %d", errno);
printf("accept socket ...\n");
if (tls_accept_socket(ctx, &cctx, clfd) != 0)
err(1, "tls_accept_socket: %s", tls_error(ctx));
/*
** receive message from client
*/
printf("waiting message from client ...\n");
if((readlen = tls_read(cctx, buf, sizeof(buf))) < 0)
err(1, "tls_read: %s", tls_error(cctx));
printf("received message: [%*.*s]\n", readlen, readlen, buf);
/*
** clean up all
*/
if (tls_close(cctx) != 0)
err(1, "tls_close: %s", tls_error(cctx));
tls_free(cctx);
tls_free(ctx);
tls_config_free(cfg);
return(0);
}
/* libtls_util.c */
#include <stdio.h>
#include <time.h>
#include <err.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <tls.h>
int
setup_socket(int port)
{
int sock, sock_ret;
struct sockaddr_in addr;
struct sockaddr_in client;
int len;
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1)
return(-1);
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = INADDR_ANY;
if (bind(sock, (struct sockaddr *) &addr, sizeof(addr)) != 0)
return(-1);
if (listen(sock, 3) != 0)
return(-1);
len = sizeof(client);
if ((sock_ret = accept(sock, (struct sockaddr *) &client, &len)) == -1)
return(-1);
return sock_ret;
}
int
dump_session_info(struct tls *ctx, const char *name)
{
const char *p;
time_t time;
struct tm *tm;
if (tls_peer_cert_provided(ctx) == 1)
printf("tls_peer_cert_provided: YES\n");
else {
printf("tls_peer_cert_provided: NO\n");
return(-1);
}
if (tls_peer_cert_contains_name(ctx, name) == 1)
printf("tls_peer_cert_contains_name: %s\n", name);
else
printf("tls_peer_cert_contains_name: invalid\n");
if ((p = tls_peer_cert_issuer(ctx)) == NULL)
err(1, "tls_peer_cert_issuer: %s", tls_error(ctx));
printf("tls_peer_cert_issuer: %s\n", p);
if ((p = tls_peer_cert_subject(ctx)) == NULL)
err(1, "tls_peer_cert_subject: %s", tls_error(ctx));
printf("tls_peer_cert_subject: %s\n", p);
if ((p = tls_peer_cert_hash(ctx)) == NULL)
err(1, "tls_peer_cert_hash: %s", tls_error(ctx));
printf("tls_peer_cert_hash: %s\n", p);
if ((time = tls_peer_cert_notbefore(ctx)) < 0)
err(1, "tls_peer_cert_notbefore: %s", tls_error(ctx));
tm = localtime(&time);
printf("tls_peer_cert_notbefore: %04d/%02d/%02d %02d:%02d:%02d\n",
1900 + tm->tm_year, tm->tm_mon + 1, tm->tm_mday,
tm->tm_hour, tm->tm_min, tm->tm_sec);
if ((time = tls_peer_cert_notafter(ctx)) < 0)
err(1, "tls_peer_cert_notafter: %s", tls_error(ctx));
tm = localtime(&time);
printf("tls_peer_cert_notafter: %04d/%02d/%02d %02d:%02d:%02d\n",
1900 + tm->tm_year, tm->tm_mon + 1, tm->tm_mday,
tm->tm_hour, tm->tm_min, tm->tm_sec);
if ((p = tls_conn_version(ctx)) == NULL)
err(1, "tls_conn_version: %s", tls_error(ctx));
printf("tls_conn_version: %s\n", p);
if ((p = tls_conn_cipher(ctx)) == NULL)
err(1, "tls_conn_cipher: %s", tls_error(ctx));
printf("tls_conn_cipher: %s\n", p);
return(0);
}
# Makefile
all :: libtls_server libtls_client
libtls_server : libtls_server.o libtls_util.o
$(CC) -g -o $@ $^ -L/usr/local/lib -ltls -lssl -lcrypto
libtls_client : libtls_client.o libtls_util.o
$(CC) -g -o $@ $^ -L/usr/local/lib -ltls -lssl -lcrypto
.c.o :
$(CC) -g -c -o $@ $< -I/usr/local/include
clean :
/bin/rm -f libtls_server libtls_client libtls_*.o
-----BEGIN CERTIFICATE-----
MIIDMDCCAhgCCQD1PCxuVuqbXjANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJK
UDEOMAwGA1UECAwFVG9reW8xGzAZBgNVBAoMElRFU1RfRFVNTVlfQ09NUEFOWTEe
MBwGA1UEAwwVdGVzdENBLnRlc3RfZHVtbXkuY29tMB4XDTE2MDQyMDA3NDc0M1oX
DTI2MDQxODA3NDc0M1owWjELMAkGA1UEBhMCSlAxDjAMBgNVBAgMBVRva3lvMRsw
GQYDVQQKDBJURVNUX0RVTU1ZX0NPTVBBTlkxHjAcBgNVBAMMFXRlc3RDQS50ZXN0
X2R1bW15LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMm+MK2z
J9uv3XaZkb78IAZdc10RjVPT70NMX/ytqEL3o2GzAzbyEYnCdWgcZSAph2EPQHin
+pUjPbB86lNUCEdzKbIkyiVjCxY1v3GtItM8/ds3i3GzfY3bVNIwGaeRtVoTW/ER
PBBEHYC8GZHKOYfmojgv57/w5eQ/RBxgyTWPKRCffQWOz+0cv7F/mjr7THMY/ayb
j3eAcXxH+kOKPRlGggnhY8VLfJULcN5Y1RkG40rtRBjPopUvMLNGdwzP/wCVjKN7
XxrdnZsjxl7CMw1GTPFcczVIZbnenHSU/BXu9icAuta8qYyfPp/TxgS6kLuXzPku
I0FUlptv8lIYF6kCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAm+vw9/5YttMQ1SW4
3HadS6EV6kob4ar7AcqGfCooqBCcMh8JE6fD5ZU3wW5WyNyvuVoLKxZgiOx4xIq4
FeMkVFLTH0ioTcdiO0VPB6DpU8ufpFyBe+8Em9cH9CqmEjmICDRouWu3gefkS/NZ
LuAI/vBWIPjESln7K8gRcXMLnHuhdoO4I9rZB96Jmbf3Q61RDY5jRxst4V6a8DVV
tCpr4DfVK37Cl3f0AnL2KRU2435R4wSGZQavc4JnrpAxk8HvTmrLhquJG3aabHim
L7BbMgUCytRSnbxBCnR+mPJgPOIFGg5X4ex1GdAFoLraR/qU48YpKaWw5ARJ2oM0
7mSYyg==
-----END CERTIFICATE-----
Certificate:
Data:
Version: 1 (0x0)
Serial Number: 3 (0x3)
Signature Algorithm: sha1WithRSAEncryption
Issuer: C=JP, ST=Tokyo, O=TEST_DUMMY_COMPANY, CN=testCA.test_dummy.com
Validity
Not Before: Apr 20 07:47:44 2016 GMT
Not After : Apr 18 07:47:44 2026 GMT
Subject: C=JP, ST=Tokyo, O=TEST_DUMMY_COMPANY, CN=localhost.test_dummy.com
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
00:e4:b5:88:4e:07:74:70:8c:0a:3f:d4:c4:59:67:
66:a0:e9:90:98:5f:14:df:04:7d:e1:11:3b:45:5a:
3f:ff:26:90:6d:a5:ac:01:81:89:87:d9:46:71:70:
fa:b2:31:7e:cc:84:37:c7:42:4b:6e:50:1c:12:cd:
88:db:1f:1e:fa:64:7c:fd:cb:0a:ea:96:f8:09:11:
b6:5e:de:24:c0:34:c8:90:a1:fe:9d:72:26:90:d6:
e4:82:82:7b:6a:3e:b3:19:c2:85:71:55:96:c9:a7:
6e:fc:77:32:de:3b:ae:aa:9b:67:0b:38:65:50:9d:
65:4c:d4:1a:b2:a9:44:23:ad:03:d3:8e:06:54:9f:
7a:94:29:a2:ad:f9:27:65:e0:ee:14:35:ba:fe:93:
61:24:74:b4:8d:fb:bd:8e:dd:0d:e4:3f:8e:c5:a1:
bf:45:d6:04:dd:f8:81:3f:97:c8:db:f6:f7:b1:5f:
eb:63:81:2f:cf:b9:8d:00:ba:62:fa:4d:cf:56:89:
0b:d4:b4:49:a2:1e:f6:71:cc:96:56:d0:23:f6:cd:
7a:5e:97:4c:07:4b:e5:0e:3d:cb:dc:2a:27:ee:0e:
67:cb:23:6d:a9:28:04:4f:a0:cb:8a:cf:a6:64:55:
4d:a9:50:91:d5:1c:20:b1:de:67:f5:2b:5d:a9:73:
bb:43
Exponent: 65537 (0x10001)
Signature Algorithm: sha1WithRSAEncryption
75:b5:cf:c1:f2:fb:d0:7c:f4:da:74:7a:7a:7e:1c:c7:c9:ca:
7e:90:f6:70:33:0d:50:7e:30:c5:c6:e0:2c:b8:29:17:80:d6:
34:fd:0a:5e:f3:4e:c4:43:d9:97:2c:c2:14:80:50:51:67:01:
62:db:03:74:dd:50:a4:08:67:be:96:b0:cd:f5:26:83:a4:69:
23:34:09:68:9a:6b:72:fd:27:c7:35:d9:54:63:d3:a4:1c:e0:
4d:1e:89:5f:0e:7b:a1:96:49:c9:54:a2:23:9a:80:8c:ad:79:
83:8a:a0:95:27:10:a5:e6:bf:59:79:44:c0:bd:c8:c7:11:7e:
c3:1c:b0:73:11:87:f6:3f:4f:7f:28:a0:83:b9:64:85:43:c6:
8a:b9:be:b4:95:e3:cc:72:8f:e7:94:c1:c2:9d:f5:ff:4c:83:
66:0f:5d:1d:e3:cf:b1:10:58:0a:9e:66:d1:10:bc:a0:a1:34:
b3:fd:01:d7:b6:86:f4:e1:f2:b5:49:a7:68:e6:7d:2b:c7:23:
c1:71:dd:2a:f3:04:84:40:d2:0d:ee:67:d2:ef:15:64:86:b2:
50:98:56:47:1a:44:62:13:f1:7b:f2:6a:f4:88:75:03:4e:74:
d7:94:1d:cc:bc:e3:f0:bd:1f:81:e5:5f:af:18:2f:7b:e7:79:
58:82:90:3a
-----BEGIN CERTIFICATE-----
MIIDKzCCAhMCAQMwDQYJKoZIhvcNAQEFBQAwWjELMAkGA1UEBhMCSlAxDjAMBgNV
BAgMBVRva3lvMRswGQYDVQQKDBJURVNUX0RVTU1ZX0NPTVBBTlkxHjAcBgNVBAMM
FXRlc3RDQS50ZXN0X2R1bW15LmNvbTAeFw0xNjA0MjAwNzQ3NDRaFw0yNjA0MTgw
NzQ3NDRaMF0xCzAJBgNVBAYTAkpQMQ4wDAYDVQQIDAVUb2t5bzEbMBkGA1UECgwS
VEVTVF9EVU1NWV9DT01QQU5ZMSEwHwYDVQQDDBhsb2NhbGhvc3QudGVzdF9kdW1t
eS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDktYhOB3RwjAo/
1MRZZ2ag6ZCYXxTfBH3hETtFWj//JpBtpawBgYmH2UZxcPqyMX7MhDfHQktuUBwS
zYjbHx76ZHz9ywrqlvgJEbZe3iTANMiQof6dciaQ1uSCgntqPrMZwoVxVZbJp278
dzLeO66qm2cLOGVQnWVM1BqyqUQjrQPTjgZUn3qUKaKt+Sdl4O4UNbr+k2EkdLSN
+72O3Q3kP47Fob9F1gTd+IE/l8jb9vexX+tjgS/PuY0AumL6Tc9WiQvUtEmiHvZx
zJZW0CP2zXpel0wHS+UOPcvcKifuDmfLI22pKARPoMuKz6ZkVU2pUJHVHCCx3mf1
K12pc7tDAgMBAAEwDQYJKoZIhvcNAQEFBQADggEBAHW1z8Hy+9B89Np0enp+HMfJ
yn6Q9nAzDVB+MMXG4Cy4KReA1jT9Cl7zTsRD2ZcswhSAUFFnAWLbA3TdUKQIZ76W
sM31JoOkaSM0CWiaa3L9J8c12VRj06Qc4E0eiV8Oe6GWSclUoiOagIyteYOKoJUn
EKXmv1l5RMC9yMcRfsMcsHMRh/Y/T38ooIO5ZIVDxoq5vrSV48xyj+eUwcKd9f9M
g2YPXR3jz7EQWAqeZtEQvKChNLP9Ade2hvTh8rVJp2jmfSvHI8Fx3SrzBIRA0g3u
Z9LvFWSGslCYVkcaRGIT8XvyavSIdQNOdNeUHcy84/C9H4HlX68YL3vneViCkDo=
-----END CERTIFICATE-----
-----BEGIN ENCRYPTED PRIVATE KEY-----
MIIFHzBJBgkqhkiG9w0BBQ0wPDAbBgkqhkiG9w0BBQwwDgQIKV3cZODlQCUCAggA
MB0GCWCGSAFlAwQBKgQQ5mBHXYhwLvtBs0O7+s7bQASCBNBePRD77gZFHQU6dAPu
auIAGpvE3TQuYcdWVQTqx29/tKVsj4zHHaEOb6thMJ4aBgw+KUXti8hV88XfUUBC
zkftAn9Tx7l1TKhRifcBZT7oSvngOFeUHR6FlxuCyPGI45UzprC4O25xtzYsNVTS
C8bUtEbManh8f9zZaqEfyRwOhoZ2kWg91+ZX+O90jRis7Sh+n70H32v9iIiM3SkC
6Yv/uhMoZlFkoE9k61Vl+GBwozIKCUYqufXRX546jVowA9mEaTJyRAda9QCZy491
9e6+8tMTXiWemYCOIrHzZV8ncQnKSmCHh2dJMEWMOK88bXGJVZQtHq65fym/CoVj
/3GKybrKD5zN9qCJp6I2uBRoEa8NbRXozyaN7GscXUtfAQEBltCxDGlpZg1WF/yQ
eH1jiZH8l2VR2sYJxFoKb9iUiIHAJ24kCyrNB4YaiWxrpVfcgM415moHG16eWSJV
P4IzddsmBMBSzTztoFdqBtl7nBKx3R0AkH5xm8/mT7yobjWW3I6ON7/q8SbNAXED
SwSnBgjTGwW6b85hpmmEqJuzmV3FJx4DAxKp5Wt0/VH/5f8/yx7/dhIymOvOwQ4W
5zbCCyxmML4EAu/3o85bq31+EErvnf2MHE7WjeS729Lh5I3/Z/XVla8HcnCTful7
6LI+ub+BVy1gIzThH13M8ErFulQHm3RiZie6s+GKYkZgU6bg6X4+jZ9hO5T+cccq
oUzP0KRyxQpyGqzddrxJQnaUVViqtKOzuMLMBwv4ohRNUZzMSfh52qrb0N6U08BX
ySh1c1y+/qaQyzx/McPbOrmoyRpfryPqiIfJKAcb3PdVLbHBjxHkvahmFWMhuC6O
GzrrsYm7mBBEv4gcSv09s8IMemj2eFUY8ZqjOQ5RuHSFnitk5vMyMKAGcEM8Ioe3
l38dqpX53blTh9zfUxnsENw7gkK8AoFLGIZfFnKjYDCQzH6rK5X2bt5rF/8X9RGL
5HOt4SngU2wIY/UqUs5XnKac8zkPXuhOPYoGfOCmqCmVS850idO3N00rsBtonP6I
c7nw3m3/iytoXjpHDLbOAucHh2iShk2CZ3BsEXqbodGj3NfDNlVRgRw7vtsj3Z7P
qAz7y381SwT4ShGJHlctUzxfAhlCslsC9YK62xHx3ydB6cFPrRkpUwMGIZQ9XxnY
Op360QLTlHNQxbKttR6dqNhglEml7dZoEtsW+ZmGvEADE86M2wJjktF94IISrrM5
RIYk2SxVUSASDttS3K1O6O/QUfqxUEbpGsaUDk7hcrO1Qfg3FfoGc0HPjJrZtDrS
xW5JHCt5pwJN6kVc3AccuevX+oLhpkRsa7IvBtReBGcPRLjwpBiuqGhKNK8GB0QB
9L/aRncZ8vv06t+99FYenV6+SmKu5Jkm4XhKMSNxDnsfGozaXYIB8bwa+NmvQ0Y4
xI3yt2sIhyTTfhX8z6tdBmJrAU3vzEO0rmGtgpMSp/cv+q5jzkG7ig8Tj8dle081
MkICbIEIE/BxDtoRI7WouewOpGXaVXSxWUbwaNbIz9+AYRsH/F+sqGFRyQ7ZNQ8c
O9upLvxBp2XpY44LANBu/hcloOKeUoAO8Jv803qlDQ8oNNvV+DArKm7DwdiORUZ+
saz54WcJOKsWt7wMEkwSacd+Bg==
-----END ENCRYPTED PRIVATE KEY-----
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment