initial tutorial update

pull/1/head
CJ 2014-07-01 09:33:25 -06:00
commit 2e135f0f4f
9 changed files with 382 additions and 50 deletions

29
.gitignore vendored
View File

@ -21,3 +21,32 @@
*.i*86
*.x86_64
*.hex
# Example executables
/dtls/client-dtls-nonblocking
/dtls/client-dtls-resume
/dtls/client-dtls
/dtls/client-udp
/dtls/server-dtls-nonblocking
/dtls/server-dtls-threaded
/dtls/server-dtls
/dtls/server-udp
/psk/client-psk-nonblocking
/psk/client-psk-resume
/psk/client-psk
/psk/client-tcp
/psk/server-psk-nonblocking
/psk/server-psk-threaded
/psk/server-psk
/psk/server-tcp
/tls/client-tls-nonblocking
/tls/client-tls-resume
/tls/client-tls
/tls/client-tcp
/tls/server-tls-nonblocking
/tls/server-tls-threaded
/tls/server-tls
/tls/server-tcp

View File

@ -1,4 +1,78 @@
wolfssl-examples
================
wolfSSL Example Applications
============================
This repository contains example applications, written in C, which
demonstrate how to use the CyaSSL lightweight SSL/TLS library for secure
communication.
Each directory represents a unique topic (SSL/TLS, DTLS, PSK, etc.) and
contains a Makefile as well as a simple tutorial on the given topic.
## Current Examples
#### DTLS (Datagram TLS)
This directory contains examples of using DTLS, with client and server
examples demonstrating UDP, DTLS, non-blocking, session resumption,
and multi-threading.
When compiling CyaSSL for use with these examples, CyaSSL will need to be
compiled with DTLS support:
```
cd cyassl-[version]
./configure --enable-dtls
```
Examples in this directory may be compiled using:
```
cd ./dtls
make
```
#### PSK (Pre-Shared Keys)
This directory contains examples of using PSK, with client and server examples
demonstrating TCP/IP, PSK, non-blocking, session resumption, and
multi-threading.
When compiling CyaSSL for use with these examples, CyaSSL will need to be
compiled with PSK support:
```
cd cyassl-[version]
./configure --enable-psk
```
Examples in this directory may be compiled using:
```
cd ./dtls
make
```
#### SSL/TLS
This directory contains examples of using SSL/TLS, with client and server
examples demonstrating TCP/IP, SSL/TLS, non-blocking, session resumption, and
multi-threading.
Examples in this directory may be compiled using:
```
cd ./dtls
make
```
## Notes
When necessary, examples will use the example certificates and keys located
in the ./certs directory. These certificates and keys have been pulled in from
the main CyaSSL repository.
## Support
Please contact wolfSSL at support@wolfssl.com with any questions, bug fixes,
or suggested feature additions.
Example applications using the CyaSSL lightweight SSL/TLS library

View File

@ -3,3 +3,227 @@ TCP/PSK Tutorial
< TODO >
# **Tutorial for adding Cyassl Security and PSK (Pre shared Keys) to a Simple Server.**
1. Include the CyaSSL compatibility header:
```
#include <cyassl/ssl.h>
```
2. Change all calls from read() or recv() to CyaSSL_read(), in the simple server
```
read(sockfd, recvline, MAXLINE)
becomes
CyaSSL_read(ssl, recvline, MAXLINE)
```
* (CyaSSL_read on first use also calls CyaSSL_accept if not explicitly
called earlier in code.)
3. Change all calls from write() or send() to CySSL_write(), in the simple client
```
write(sockfd, sendline, strlen(sendline))
becomes
CyaSSL_write(ssl, sendline, strlen(sendline))
```
4. Run the CyaSSL method to initalize CyaSSL
```
CyaSSL_Init()
```
5. Create a ctx pointer that contains using the following process.
```
CYASSL_CTX* ctx;
if ((ctx = CyaSSL_CTX_new(CyaSSLv23_server_method())) == NULL)
err_sys(“CyaSSL_CTX_new error”);
```
6. In the servers main loop for accepting clients create a CYASSL pointer. Once
a new client is accepted create a CyaSSL object and associate that object with
the socket that the client is on. After using the CyaSSL object it should be
freed and also before closing the program the ctx pointer should be freed and a
CyaSSL cleanup method called.
```
CYASSL* ssl;
CyaSSL_set_fd(ssl, “integer returned from accept”);
CyaSSL_free(ssl);
CyaSSL_CTX_free(ctx);
CyaSSL_Cleanup();
```
# Now adding Pre-Shared Keys (PSK) to the CyaSSL Simple Server:
1. Build CyaSSL with pre shared keys enabled executing the following commands
in CyaSSLs root directory. Depending on file locations sudo may be needed when
running the commands.
```
./configure --enable-psk
make
make install
```
2. Set up the psk suit with using the CyaSSL callback, identity hint, and cipher list methods. These methods get called immediately after the process of setting up ctx.
```
CyaSSL_CTX_set_psk_server_callback(ctx, my_psk_server_cb);
CyaSSL_CTX_use_psk_identity_hint(ctx, “cyassl server”);
CyaSSL_CTX_set_cipher_list(ctx, “PSK-AES128-CBC-SHA256”);
```
* PSK-AES128-CBC-SHA256 creates the cipher list of having pre shared keys
with advanced encryption security using 128 bit key with cipher block
chaining using secure hash algorithm.
3. Add the my_psk_server_cb function as follows. This is a function needed that
is passed in as an argument to the CyaSSL callback.
```
static inline unsigned int my_psk_client_cb(CYASSL* ssl, char* identity, unsigned
char* key, unsigned int key_max_len) {
(void)ssl;
(void)key_max_len;
if (strncmp(identity, "Client_identity", 15) != 0)
return 0;
/* test key n hex is 0x1a2b3c4d , in decimal 439,041,101, we're using
* unsigned binary */
key[0] = 26;
key[1] = 43;
key[2] = 60;
key[3] = 77;
return 4;
}
```
Example Makefile for Simple Cyass PSK Client:
```
CC=gcc
OBJ = client-psk.o
CFLAG=-Wall
%.o: %.c $(DEPS)
$(CC) -c -o $@ $< $(CFLAGS)
client-psk: client-psk.c
$(CC) -Wall -o client-psk client-psk.c -lcyassl
.PHONY: clean
clean:
rm -f *.o client-psk
```
The -lcyassl will link the Cyassl Libraries to your program
The makefile for the server is going to be similar to that of the client. If
the user wants separate makefiles just make a use the same set up of the client
makefile and replace every instance of client-psk with server-psk. To combine
make files just add a server-psk with similar ending to each time client-psk is
referenced and change the target. There will also need to be a target for when
compiling all targets.
```
all: server-psk client-psk
server-psk: server-psk.c
$(CC) -Wall -o server-psk server-psk.c -lcyassl
```
# **Concurrent Server**
The main thread accepts clients and for each client accepted a new thread is
spawned that then handles the typical server processes.
1. To use multiple threads include the pthread header file.
**`#include <pthread.h>`**
2. When creating multiple threads the state of variables can become an issue.
Since in the example, CYASSL_CTX* is not changed after being initially set we
can make it a global variable and allow all threads read access while they are
processing without having to lock the memory.
3. After the main thread accepts a client, call the pthread_create function.
```
pthread_create(pthread_t* thread, int attribute, void* function, void* arg)
```
4. In the example the function passed to pthread_create accepts one void *
argument which is the socket the client is on. The function then performs the
process of creating a new SSL object, reading and writing to the client, freeing
the SSL object, and then terminating the thread.
```
/*
*Process handled by a thread.
*/
void* cyassl_thread(void* fd)
{
CYASSL* ssl;
int connfd = (int)fd;
int n; /* length of string read */
char buf[MAXLINE]; /* string read from client */
char response[22] = "I hear ya for shizzle";
/* create CYASSL object and respond */
if ((ssl = CyaSSL_new(ctx)) == NULL)
err_sys("CyaSSL_new error");
CyaSSL_set_fd(ssl, connfd);
/* respond to client */
n = CyaSSL_read(ssl, buf, MAXLINE);
if (n > 0) {
printf("%s\n", buf);
if (CyaSSL_write(ssl, response, 22) > 22) {
err_sys("respond: write error");
}
}
if (n < 0) {
err_sys("respond: read error");
}
/* closes the connections after responding */
CyaSSL_shutdown(ssl);
CyaSSL_free(ssl);
if (close(connfd) == -1)
err_sys("close error");
pthread_exit( NULL);
}
```
5. Void* arg is the argument that gets passed into cyassal_thread when
pthread_create is called. In this example that argument is used to pass the
socket value that the client for the current thread is on.

View File

@ -26,7 +26,7 @@ server-tls-nonblocking: server-tls-nonblocking.o
$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
server-tls-threaded: server-tls-threaded.o
$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
$(CC) -o $@ $^ $(CFLAGS) $(LIBS) -lpthread
.PHONY: clean all

View File

@ -34,14 +34,16 @@
#define DEFAULT_PORT 11111
int AcceptAndRead();
int AcceptAndRead(socklen_t sockfd);
int AcceptAndRead(int sockfd, struct sockaddr_in clientAddr)
int AcceptAndRead(socklen_t sockfd)
{
int size = sizeof(clientAddr);
struct sockaddr_in clientAddr;
socklen_t size = sizeof(clientAddr);
int ret = 0;
/* Wait until a client connects */
int connd = accept(sockfd, (struct sockaddr *)&clientAddr, &size);
int connd = accept(sockfd,(struct sockaddr *)&clientAddr, &size);
/* If fails to connect, loop back up and wait for a new connection */
if (connd == -1){
@ -60,7 +62,7 @@ int AcceptAndRead(int sockfd, struct sockaddr_in clientAddr)
bzero(&buff, sizeof(buff));
/* Read the client data into our buff array */
if (read(connd, buff, sizeof(buff)-1) > 0){
if ((ret = read(connd, buff, sizeof(buff)-1)) > 0){
/* Print any data the client sends to the console */
printf("Client: %s\n", buff);
@ -68,7 +70,8 @@ int AcceptAndRead(int sockfd, struct sockaddr_in clientAddr)
char reply[] = "I hear ya fa shizzle!\n";
/* Reply back to the client */
write(connd, reply, sizeof(reply)-1);
if ((ret = write(connd, reply, sizeof(reply)-1)) < 0)
printf("write error\n");
}
/* If the client disconnects break the loop */
else
@ -92,17 +95,17 @@ int main()
*/
/* Identify and access the sockets */
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
socklen_t sockfd = socket(AF_INET, SOCK_STREAM, 0);
int exit = 0; /* 0 = false, 1 = true */
/* If positive value, the socket is valid */
if(sockfd < 0){
if(sockfd == -1){
printf("ERROR: failed to create the socket\n");
return 1; /* Kill the server with exit status 1 */
}
/* Server and client socket address structures */
struct sockaddr_in serverAddr, clientAddr;
struct sockaddr_in serverAddr;
/* Initialize the server address struct to zero */
memset((char *)&serverAddr, 0, sizeof(serverAddr));
@ -125,7 +128,7 @@ int main()
printf("Waiting for a connection...\n");
/* Accept client connections and read from them */
exit = AcceptAndRead(sockfd, clientAddr);
exit = AcceptAndRead(sockfd);
}
/* Close the open sockets */

View File

@ -43,14 +43,14 @@
*/
enum read_write_t {WRITE, READ, ACCEPT};
int AcceptAndRead(CYASSL_CTX* ctx, int socketfd,
int AcceptAndRead(CYASSL_CTX* ctx, socklen_t socketfd,
struct sockaddr_in clientAddr);
int TCPSelect(int socketfd);
int NonBlocking_ReadWriteAccept(CYASSL* ssl, int socketfd,
int TCPSelect(socklen_t socketfd);
int NonBlocking_ReadWriteAccept(CYASSL* ssl, socklen_t socketfd,
enum read_write_t rw);
/* Check if any sockets are ready for reading and writing and set it */
int TCPSelect(int socketfd)
int TCPSelect(socklen_t socketfd)
{
fd_set recvfds, errfds;
int nfds = socketfd + 1;
@ -75,7 +75,7 @@ int TCPSelect(int socketfd)
}
/* Checks if NonBlocking I/O is wanted, if it is wanted it will
* wait until it's available on the socket before reading or writing */
int NonBlocking_ReadWriteAccept(CYASSL* ssl, int socketfd,
int NonBlocking_ReadWriteAccept(CYASSL* ssl, socklen_t socketfd,
enum read_write_t rw)
{
const char reply[] = "I hear ya fa shizzle!\n";
@ -144,12 +144,9 @@ int NonBlocking_ReadWriteAccept(CYASSL* ssl, int socketfd,
return 1;
}
int AcceptAndRead(CYASSL_CTX* ctx, int socketfd, struct sockaddr_in clientAddr)
int AcceptAndRead(CYASSL_CTX* ctx, socklen_t socketfd, struct sockaddr_in clientAddr)
{
int size = sizeof(clientAddr);
int ret = 0;
int err = 0;
CYASSL* ssl;
socklen_t size = sizeof(clientAddr);
/* Wait until a client connects */
int connd = accept(socketfd, (struct sockaddr *)&clientAddr, &size);
@ -161,7 +158,7 @@ int AcceptAndRead(CYASSL_CTX* ctx, int socketfd, struct sockaddr_in clientAddr)
/* If it connects, read in and reply to the client */
else {
printf("Client connected successfully!\n");
CYASSL* ssl;
if ( (ssl = CyaSSL_new(ctx)) == NULL) {
fprintf(stderr, "CyaSSL_new error.\n");
exit(EXIT_FAILURE);
@ -186,8 +183,8 @@ int AcceptAndRead(CYASSL_CTX* ctx, int socketfd, struct sockaddr_in clientAddr)
if (NonBlocking_ReadWriteAccept(ssl, socketfd, WRITE) == 0)
break;
}
CyaSSL_free(ssl); /* Free the CYASSL object */
}
CyaSSL_free(ssl); /* Free the CYASSL object */
close(connd); /* close the connected socket */
return 0;
@ -201,9 +198,9 @@ int main()
* Sets the type to be Stream based (TCP),
* 0 means choose the default protocol.
*/
int socketfd = socket(AF_INET, SOCK_STREAM, 0);
socklen_t socketfd = socket(AF_INET, SOCK_STREAM, 0);
int loopExit = 0; /* 0 = False, 1 = True */
int ret = 0; /* Return variable */
int ret = 0;
int on = 1;
/* Set nonblocking */
@ -226,7 +223,7 @@ int main()
socklen_t len = sizeof(on);
/* If positive value, the socket is valid */
if (socketfd < 0) {
if (socketfd == -1) {
printf("ERROR: failed to create the socket\n");
exit(EXIT_FAILURE); /* Kill the server with exit status 1 */
}
@ -245,7 +242,7 @@ int main()
}
/* Load server certificate into CYASSL_CTX */
if (CyaSSL_CTX_use_certificate_file(ctx, "certs/server-cert.pem",
if (CyaSSL_CTX_use_certificate_file(ctx, "../certs/server-cert.pem",
SSL_FILETYPE_PEM) != SSL_SUCCESS) {
fprintf(stderr, "Error loading certs/server-cert.pem, please check"
"the file.\n");
@ -253,7 +250,7 @@ int main()
}
/* Load server key into CYASSL_CTX */
if (CyaSSL_CTX_use_PrivateKey_file(ctx, "certs/server-key.pem",
if (CyaSSL_CTX_use_PrivateKey_file(ctx, "../certs/server-key.pem",
SSL_FILETYPE_PEM) != SSL_SUCCESS) {
fprintf(stderr, "Error loading certs/server-key.pem, please check"
"the file.\n");

View File

@ -39,7 +39,7 @@
#define DEFAULT_PORT 11111
int AcceptAndRead(int sockfd, struct sockaddr_in clientAddr);
int AcceptAndRead(socklen_t sockfd, struct sockaddr_in clientAddr);
void *ThreadHandler(void* socketDesc);
/* Create a ctx pointer for our ssl */
@ -93,12 +93,14 @@ void *ThreadHandler(void* socketDesc)
break;
}
}
exit(EXIT_SUCCESS);
}
int AcceptAndRead(int sockfd, struct sockaddr_in clientAddr)
int AcceptAndRead(socklen_t sockfd, struct sockaddr_in clientAddr)
{
int size = sizeof(clientAddr);
socklen_t size = sizeof(clientAddr);
int connd; /* Identify and access the clients connection */
pthread_t thread_id;
@ -128,7 +130,7 @@ int main()
* Sets the type to be Stream based (TCP),
* 0 means choose the default protocol.
*/
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
socklen_t sockfd = socket(AF_INET, SOCK_STREAM, 0);
int ret = 0; /* Return Variable */
int loopExit = 0; /* 0 = False, 1 = True */
@ -147,7 +149,7 @@ int main()
CyaSSL_Init();
/* If positive value, the socket is valid */
if (sockfd < 0) {
if (sockfd == -1) {
printf("ERROR: failed to create the socket\n");
return EXIT_FAILURE;
}
@ -159,7 +161,7 @@ int main()
}
/* Load server certificate into CYASSL_CTX */
if (CyaSSL_CTX_use_certificate_file(ctx, "certs/server-cert.pem",
if (CyaSSL_CTX_use_certificate_file(ctx, "../certs/server-cert.pem",
SSL_FILETYPE_PEM) != SSL_SUCCESS) {
fprintf(stderr, "Error loading certs/server-cert.pem, please check"
"the file.\n");
@ -167,7 +169,7 @@ int main()
}
/* Load server key into CYASSL_CTX */
if (CyaSSL_CTX_use_PrivateKey_file(ctx, "certs/server-key.pem",
if (CyaSSL_CTX_use_PrivateKey_file(ctx, "../certs/server-key.pem",
SSL_FILETYPE_PEM) != SSL_SUCCESS) {
fprintf(stderr, "Error loading certs/server-key.pem, please check"
"the file.\n");

View File

@ -38,16 +38,15 @@
#define DEFAULT_PORT 11111
int AcceptAndRead(CYASSL_CTX* ctx, int sockfd, struct sockaddr_in clientAddr);
int AcceptAndRead(CYASSL_CTX* ctx, socklen_t sockfd, struct sockaddr_in
clientAddr);
int AcceptAndRead(CYASSL_CTX* ctx, int sockfd, struct sockaddr_in clientAddr)
int AcceptAndRead(CYASSL_CTX* ctx, socklen_t sockfd, struct sockaddr_in
clientAddr)
{
/* Create our reply message */
const char reply[] = "I hear ya fa shizzle!\n";
int size = sizeof(clientAddr);
int ret = 0;
int err = 0;
CYASSL* ssl;
socklen_t size = sizeof(clientAddr);
/* Wait until a client connects */
int connd = accept(sockfd, (struct sockaddr *)&clientAddr, &size);
@ -59,6 +58,7 @@ int AcceptAndRead(CYASSL_CTX* ctx, int sockfd, struct sockaddr_in clientAddr)
/* If it connects, read in and reply to the client */
else {
printf("Client connected successfully\n");
CYASSL* ssl;
if ( (ssl = CyaSSL_new(ctx)) == NULL) {
fprintf(stderr, "CyaSSL_new error.\n");
@ -101,8 +101,8 @@ int AcceptAndRead(CYASSL_CTX* ctx, int sockfd, struct sockaddr_in clientAddr)
break;
}
}
CyaSSL_free(ssl); /* Free the CYASSL object */
}
CyaSSL_free(ssl); /* Free the CYASSL object */
close(connd); /* close the connected socket */
return 0;
@ -119,7 +119,7 @@ int main()
* Sets the type to be Stream based (TCP),
* 0 means choose the default protocol.
*/
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
socklen_t sockfd = socket(AF_INET, SOCK_STREAM, 0);
int loopExit = 0; /* 0 = False, 1 = True */
int ret = 0; /* Return value */
/* Server and client socket address structures */
@ -129,7 +129,7 @@ int main()
CyaSSL_Init();
/* If positive value, the socket is valid */
if (sockfd < 0) {
if (sockfd == -1) {
printf("ERROR: failed to create the socket\n");
return EXIT_FAILURE; /* Kill the server with exit status 1 */
}
@ -141,7 +141,7 @@ int main()
}
/* Load server certificate into CYASSL_CTX */
if (CyaSSL_CTX_use_certificate_file(ctx, "certs/server-cert.pem",
if (CyaSSL_CTX_use_certificate_file(ctx, "../certs/server-cert.pem",
SSL_FILETYPE_PEM) != SSL_SUCCESS) {
fprintf(stderr, "Error loading certs/server-cert.pem, please check"
"the file.\n");
@ -149,7 +149,7 @@ int main()
}
/* Load server key into CYASSL_CTX */
if (CyaSSL_CTX_use_PrivateKey_file(ctx, "certs/server-key.pem",
if (CyaSSL_CTX_use_PrivateKey_file(ctx, "../certs/server-key.pem",
SSL_FILETYPE_PEM) != SSL_SUCCESS) {
fprintf(stderr, "Error loading certs/server-key.pem, please check"
"the file.\n");

View File

@ -1,6 +1,7 @@
TCP/TLS Tutorial
================
<<<<<<< HEAD
## Client TLS Tutorial
### client-tls.c
@ -25,4 +26,6 @@ to
'''c
Security(sockfd);
'''
Now we just have to make the 'Security()'
Now we just have to make the 'Security()'
=======
>>>>>>> a62664a86549dd488e2fa5ae902aa66da8b7a85d