X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=extlibs%2Ftinydtls%2Ftests%2Fdtls-server.c;h=07acd18eb1cd661d53e8f85a3da88e078a437d72;hb=edcfc3d2329da7b914771c0dcff5f42c9b74fd93;hp=d3da1a79e0270295c093bbd0a78278fb55c0fe16;hpb=b029953884356f976a4bdf560a6693bc6bcc115a;p=platform%2Fupstream%2Fiotivity.git diff --git a/extlibs/tinydtls/tests/dtls-server.c b/extlibs/tinydtls/tests/dtls-server.c index d3da1a7..07acd18 100644 --- a/extlibs/tinydtls/tests/dtls-server.c +++ b/extlibs/tinydtls/tests/dtls-server.c @@ -2,24 +2,163 @@ /* This is needed for apple */ #define __APPLE_USE_RFC_3542 +#include "iotivity_config.h" #include #include #include #include +#ifdef HAVE_UNISTD_H #include +#endif +#ifdef HAVE_NETINET_IN_H #include +#endif #include +#ifdef HAVE_SYS_SOCKET_H #include +#endif +#ifdef HAVE_SYS_TIME_H #include +#endif +#ifdef HAVE_NETDB_H #include +#endif #include +#include +#include "platform_features.h" -#include "tinydtls.h" -#include "dtls.h" -#include "debug.h" +#include "tinydtls.h" +#include "dtls.h" +#include "debug.h" + +#ifdef DTLS_X509 +#define DTLS_PRIVATE_KEY_SIZE (32) +#define DTLS_PUBLIC_KEY_SIZE (64) +#endif #define DEFAULT_PORT 20220 +/** + * @struct byte_array + * + * General purpose byte array structure. + * + * Contains pointer to array of bytes and it's length. + */ + +typedef struct +{ + uint8_t *data; /**< Pointer to the byte array */ + size_t len; /**< Data size */ +} byte_array; + + +/**@def BYTE_ARRAY_INITIALIZER + * + * Initializes of existing byte array pointer to \a NULL. + */ +#undef BYTE_ARRAY_INITIALIZER +#define BYTE_ARRAY_INITIALIZER {NULL, 0} + +#ifdef DTLS_X509 +#define X509_OPTIONS "x:r:u:" +#define SERVER_CRT_LEN 295 +static const unsigned char g_server_certificate[SERVER_CRT_LEN] = { + 0x00, 0x01, 0x24, + 0x30, 0x82, 0x01, 0x20, 0x30, 0x81, 0xc4, 0xa0, + 0x03, 0x02, 0x01, 0x01, 0x02, 0x02, 0x02, 0x37, + 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, + 0x3d, 0x04, 0x03, 0x02, 0x05, 0x00, 0x30, 0x17, + 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x0c, 0x0c, 0x4c, 0x6f, 0x63, 0x61, 0x6c, + 0x20, 0x49, 0x53, 0x53, 0x55, 0x45, 0x52, 0x30, + 0x1e, 0x17, 0x0d, 0x31, 0x33, 0x30, 0x31, 0x30, + 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, + 0x17, 0x0d, 0x34, 0x39, 0x30, 0x31, 0x30, 0x31, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, + 0x17, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x0c, 0x0c, 0x4c, 0x6f, 0x63, 0x61, + 0x6c, 0x20, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, + 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, + 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, + 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, + 0x42, 0x00, 0x04, 0x07, 0x88, 0x10, 0xdc, 0x62, + 0xd7, 0xe6, 0x9b, 0x7c, 0xad, 0x6e, 0x78, 0xb0, + 0x5f, 0x9a, 0x00, 0x11, 0x74, 0x2c, 0x8b, 0xaf, + 0x09, 0x65, 0x7c, 0x86, 0x8e, 0x55, 0xcb, 0x39, + 0x55, 0x72, 0xc6, 0x65, 0x71, 0xcd, 0x03, 0xdc, + 0x2a, 0x4f, 0x46, 0x5b, 0x14, 0xc8, 0x27, 0x74, + 0xab, 0xf4, 0x1f, 0xc1, 0x35, 0x0d, 0x42, 0xbc, + 0xc2, 0x9f, 0xb5, 0xc1, 0x79, 0xb6, 0x8b, 0xca, + 0xdb, 0xff, 0x82, 0x30, 0x0c, 0x06, 0x08, 0x2a, + 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x05, + 0x00, 0x03, 0x49, 0x00, 0x30, 0x46, 0x02, 0x21, + 0x00, 0xb1, 0x81, 0x81, 0x92, 0x0e, 0x76, 0x7c, + 0xeb, 0xf5, 0x37, 0xde, 0x27, 0xc4, 0x01, 0xc8, + 0x96, 0xc3, 0xe5, 0x9f, 0x47, 0x7e, 0x25, 0x92, + 0xa4, 0xba, 0x22, 0x25, 0xa3, 0x81, 0x19, 0xcf, + 0x0d, 0x02, 0x21, 0x00, 0xca, 0x92, 0xbe, 0x79, + 0xc7, 0x82, 0x84, 0x64, 0xc4, 0xc4, 0xf4, 0x3d, + 0x69, 0x79, 0x68, 0xc0, 0xf1, 0xba, 0xaf, 0x6c, + 0xbb, 0xdd, 0x54, 0x7d, 0x07, 0xe7, 0x53, 0x3b, + 0xc3, 0x1b, 0x87, 0x04}; + +//default server's key pair +static const unsigned char x509_priv_key[] = { + 0xaa, 0xa3, 0x46, 0xf1, 0x3c, 0x56, 0x5d, 0x08, + 0x5e, 0x59, 0xba, 0x7f, 0xd2, 0x21, 0x62, 0xc6, + 0xcc, 0x5d, 0xfa, 0x3f, 0xb5, 0x25, 0xa9, 0x89, + 0x4f, 0x32, 0xe8, 0x2a, 0xe0, 0xee, 0x9b, 0x4c}; + +static const unsigned char x509_pub_key_x[] = { + 0x07, 0x88, 0x10, 0xdc, 0x62, 0xd7, 0xe6, 0x9b, + 0x7c, 0xad, 0x6e, 0x78, 0xb0, 0x5f, 0x9a, 0x00, + 0x11, 0x74, 0x2c, 0x8b, 0xaf, 0x09, 0x65, 0x7c, + 0x86, 0x8e, 0x55, 0xcb, 0x39, 0x55, 0x72, 0xc6}; + +static const unsigned char x509_pub_key_y[] = { + 0x65, 0x71, 0xcd, 0x03, 0xdc, 0x2a, 0x4f, 0x46, + 0x5b, 0x14, 0xc8, 0x27, 0x74, 0xab, 0xf4, 0x1f, + 0xc1, 0x35, 0x0d, 0x42, 0xbc, 0xc2, 0x9f, 0xb5, + 0xc1, 0x79, 0xb6, 0x8b, 0xca, 0xdb, 0xff, 0x82}; + +//default CA pub key +static const unsigned char x509_ca_pub_x[] = { + 0x57, 0x94, 0x7f, 0x98, 0x7a, 0x02, 0x67, 0x09, + 0x25, 0xc1, 0xcb, 0x5a, 0xf5, 0x46, 0xfb, 0xad, + 0xf7, 0x68, 0x94, 0x8c, 0xa7, 0xe3, 0xf0, 0x5b, + 0xc3, 0x6b, 0x5c, 0x9b, 0xd3, 0x7d, 0x74, 0x12 +}; + +static const unsigned char x509_ca_pub_y[] = { + 0xce, 0x68, 0xbc, 0x55, 0xf5, 0xf8, 0x1b, 0x3d, + 0xef, 0xed, 0x1f, 0x2b, 0xd2, 0x69, 0x5d, 0xcf, + 0x79, 0x16, 0xa6, 0xbd, 0x97, 0x96, 0x27, 0x60, + 0x5d, 0xd1, 0xb7, 0x93, 0xa2, 0x4a, 0x62, 0x4d +}; + +static const unsigned char client_pub_key_x[] = { + 0xe3, 0xd1, 0x67, 0x1e, 0xdc, 0x46, 0xf4, 0x19, + 0x50, 0x15, 0x2e, 0x3a, 0x2f, 0xd8, 0x68, 0x6b, + 0x37, 0x32, 0x84, 0x9e, 0x83, 0x81, 0xbf, 0x25, + 0x5d, 0xbb, 0x18, 0x07, 0x3c, 0xbd, 0xf3, 0xab}; + +static const unsigned char client_pub_key_y[] = { + 0xd3, 0xbf, 0x53, 0x59, 0xc9, 0x1e, 0xce, 0x5b, + 0x39, 0x6a, 0xe5, 0x60, 0xf3, 0x70, 0xdb, 0x66, + 0xb6, 0x80, 0xcb, 0x65, 0x0b, 0x35, 0x2a, 0x62, + 0x44, 0x89, 0x63, 0x64, 0x6f, 0x6f, 0xbd, 0xf0}; + +static unsigned char x509_server_cert[DTLS_MAX_CERT_SIZE]; +static size_t x509_server_cert_len = 0; +static unsigned char x509_server_priv[DTLS_PRIVATE_KEY_SIZE+1]; +static size_t x509_server_priv_is_set = 0; +static unsigned char x509_ca_pub[DTLS_PUBLIC_KEY_SIZE+1]; +static size_t x509_ca_pub_is_set = 0; + +static int x509_info_from_file = 0; +#endif /*DTLS_X509*/ +#ifdef DTLS_ECC static const unsigned char ecdsa_priv_key[] = { 0xD9, 0xE2, 0x70, 0x7A, 0x72, 0xDA, 0x6A, 0x05, 0x04, 0x99, 0x5C, 0x86, 0xED, 0xDB, 0xE3, 0xEF, @@ -37,7 +176,7 @@ static const unsigned char ecdsa_pub_key_y[] = { 0x1D, 0xDC, 0xF4, 0xF4, 0x2E, 0x2F, 0x26, 0x31, 0xD0, 0x43, 0xB1, 0xFB, 0x03, 0xE2, 0x2F, 0x4D, 0x17, 0xDE, 0x43, 0xF9, 0xF9, 0xAD, 0xEE, 0x70}; - +#endif /*DTLS_ECC*/ #if 0 /* SIGINT handler: set quit to 1 for graceful termination */ void @@ -46,6 +185,34 @@ handle_sigint(int signum) { } #endif +#ifdef DTLS_X509 +ssize_t +read_from_file(char *arg, unsigned char *buf, size_t max_buf_len) { + FILE *f; + ssize_t result = 0; + + f = fopen(arg, "r"); + if (f == NULL) + return -1; + + while (!feof(f)) { + size_t bytes_read; + bytes_read = fread(buf, 1, max_buf_len, f); + if (ferror(f)) { + result = -1; + break; + } + + buf += bytes_read; + result += bytes_read; + max_buf_len -= bytes_read; + } + + fclose(f); + return result; +} +#endif /*DTLS_X509*/ + #ifdef DTLS_PSK #define PSK_SERVER_HINT "Server_identity" @@ -59,6 +226,8 @@ get_psk_info(struct dtls_context_t *ctx, const session_t *session, const unsigned char *id, size_t id_len, unsigned char *result, size_t result_length) { + (void)ctx; + (void)session; struct keymap_t { unsigned char *id; size_t id_length; @@ -86,7 +255,7 @@ get_psk_info(struct dtls_context_t *ctx, const session_t *session, case DTLS_PSK_KEY: if (id) { int i; - for (i = 0; i < sizeof(psk)/sizeof(struct keymap_t); i++) { + for (i = 0; i < (int)(sizeof(psk)/sizeof(struct keymap_t)); i++) { if (id_len == psk[i].id_length && memcmp(id, psk[i].id, id_len) == 0) { if (result_length < psk[i].key_length) { dtls_warn("buffer too small for PSK"); @@ -114,6 +283,8 @@ static int get_ecdsa_key(struct dtls_context_t *ctx, const session_t *session, const dtls_ecc_key_t **result) { + (void)ctx; + (void)session; static const dtls_ecc_key_t ecdsa_key = { .curve = DTLS_ECDH_CURVE_SECP256R1, .priv_key = ecdsa_priv_key, @@ -131,15 +302,120 @@ verify_ecdsa_key(struct dtls_context_t *ctx, const unsigned char *other_pub_x, const unsigned char *other_pub_y, size_t key_size) { + (void)ctx; + (void)session; + (void)other_pub_x; + (void)other_pub_y; + (void)key_size; return 0; } #endif /* DTLS_ECC */ +#ifdef DTLS_X509 +static int +get_x509_key(struct dtls_context_t *ctx, + const session_t *session, + const dtls_ecc_key_t **result) { + (void)ctx; + (void)session; + static dtls_ecc_key_t ecdsa_key = { + .curve = DTLS_ECDH_CURVE_SECP256R1, + .priv_key = x509_priv_key, + .pub_key_x = x509_pub_key_x, + .pub_key_y = x509_pub_key_y + }; + if (x509_info_from_file) + ecdsa_key.priv_key = x509_server_priv; + + *result = &ecdsa_key; + return 0; +} + +static int +get_x509_cert(struct dtls_context_t *ctx, + const session_t *session, + const unsigned char **cert, + size_t *cert_size) +{ + (void)ctx; + (void)session; + if (x509_info_from_file) + { + *cert = x509_server_cert; + *cert_size = x509_server_cert_len; + } + else + { + *cert = g_server_certificate; + *cert_size = SERVER_CRT_LEN; + } + + return 0; +} + +static int check_certificate(byte_array cert_der_code, byte_array ca_public_key) +{ + (void)cert_der_code; + (void)ca_public_key; + return 0; +} + +static int verify_x509_cert(struct dtls_context_t *ctx, const session_t *session, + const unsigned char *cert, size_t cert_size, + unsigned char *x, + size_t x_size, + unsigned char *y, + size_t y_size) +{ + int ret; + const unsigned char *ca_pub_x; + const unsigned char *ca_pub_y; + byte_array cert_der_code = BYTE_ARRAY_INITIALIZER; + byte_array ca_public_key = BYTE_ARRAY_INITIALIZER; + unsigned char ca_pub_key[DTLS_PUBLIC_KEY_SIZE]; + (void)ctx; + (void)session; + + if (x509_info_from_file) + { + ca_pub_x = x509_ca_pub; + ca_pub_y = x509_ca_pub + DTLS_PUBLIC_KEY_SIZE/2; + } + else + { + ca_pub_x = x509_ca_pub_x; + ca_pub_y = x509_ca_pub_y; + } + + cert_der_code.data = (uint8_t *)cert; + cert_der_code.len = cert_size; + + ca_public_key.len = DTLS_PUBLIC_KEY_SIZE; + ca_public_key.data = ca_pub_key; + memcpy(ca_public_key.data, ca_pub_x, DTLS_PUBLIC_KEY_SIZE/2); + memcpy(ca_public_key.data + DTLS_PUBLIC_KEY_SIZE/2, ca_pub_y, DTLS_PUBLIC_KEY_SIZE/2); + + memcpy(x, client_pub_key_x, x_size); + memcpy(y, client_pub_key_y, y_size); + + ret = (int) check_certificate(cert_der_code, ca_public_key); + + return -ret; +} + +static int is_x509_active(struct dtls_context_t *ctx) +{ + (void)ctx; + return 0; +} +#endif /* DTLS_X509 */ + + #define DTLS_SERVER_CMD_CLOSE "server:close" #define DTLS_SERVER_CMD_RENEGOTIATE "server:renegotiate" static int -read_from_peer(struct dtls_context_t *ctx, +read_from_peer(struct dtls_context_t *ctx, session_t *session, uint8 *data, size_t len) { size_t i; for (i = 0; i < len; i++) @@ -190,7 +466,7 @@ dtls_handle_read(struct dtls_context_t *ctx) { } else { dtls_debug("got %d bytes from port %d\n", len, ntohs(session.addr.sin6.sin6_port)); - if (sizeof(buf) < len) { + if ((int)(sizeof(buf)) < len) { dtls_warn("packet was truncated (%d bytes lost)\n", len - sizeof(buf)); } } @@ -250,13 +526,21 @@ usage(const char *program, const char *version) { fprintf(stderr, "%s v%s -- DTLS server implementation\n" "(c) 2011-2014 Olaf Bergmann \n\n" "usage: %s [-A address] [-p port] [-v num] [-a enable|disable]\n" +#ifdef DTLS_X509 + " [-x file] [-r file] [-u file]" +#endif /* DTLS_X509 */ "\t-A address\t\tlisten on specified address (default is ::)\n" "\t-p port\t\tlisten on specified port (default is %d)\n" "\t-v num\t\tverbosity level (default: 3)\n" "\t-a enable|disable\t(default: disable)\n" - "\t\t\t\tenable:enable TLS_ECDH_anon_with_AES_128_CBC_SHA\n" - "\t\t\t\tdisable:disable TLS_ECDH_anon_with_AES_128_CBC_SHA\n", - program, version, program, DEFAULT_PORT); + "\t\t\t\tenable:enable TLS_ECDH_anon_with_AES_128_CBC_SHA_256\n" + "\t\t\t\tdisable:disable TLS_ECDH_anon_with_AES_128_CBC_SHA_256\n" +#ifdef DTLS_X509 + "\t-x file\tread Server certificate from file\n" + "\t-r file\tread Server private key from file\n" + "\t-u file\tread CA public key from file\n" +#endif /* DTLS_X509 */ + ,program, version, program, DEFAULT_PORT); } static dtls_handler_t cb = { @@ -268,11 +552,18 @@ static dtls_handler_t cb = { #endif /* DTLS_PSK */ #ifdef DTLS_ECC .get_ecdsa_key = get_ecdsa_key, - .verify_ecdsa_key = verify_ecdsa_key + .verify_ecdsa_key = verify_ecdsa_key, #endif /* DTLS_ECC */ +#ifdef DTLS_X509 + .get_x509_key = get_x509_key, + .verify_x509_cert = verify_x509_cert, + .get_x509_cert = get_x509_cert, + .is_x509_active = is_x509_active, +#endif + }; -int +int main(int argc, char **argv) { dtls_context_t *the_context = NULL; log_t log_level = DTLS_LOG_WARN; @@ -280,7 +571,7 @@ main(int argc, char **argv) { struct timeval timeout; int fd, opt, result; int on = 1; - int ecdh_anon_enalbe = DTLS_CIPHER_DISABLE; + dtls_cipher_enable_t ecdh_anon_enalbe = DTLS_CIPHER_DISABLE; struct sockaddr_in6 listen_addr; memset(&listen_addr, 0, sizeof(struct sockaddr_in6)); @@ -312,6 +603,47 @@ main(int argc, char **argv) { if( strcmp(optarg, "enable") == 0) ecdh_anon_enalbe = DTLS_CIPHER_ENABLE; break; +#ifdef DTLS_X509 + case 'x' : + { + ssize_t result = read_from_file(optarg, x509_server_cert, DTLS_MAX_CERT_SIZE); + if (result < 0) + { + dtls_warn("Cannot read Server certificate. Using default\n"); + } + else + { + x509_server_cert_len = result; + } + break; + } + case 'r' : + { + ssize_t result = read_from_file(optarg, x509_server_priv, DTLS_PRIVATE_KEY_SIZE+1); + if (result < 0) + { + dtls_warn("Cannot read Server private key. Using default\n"); + } + else + { + x509_server_priv_is_set = result; + } + break; + } + case 'u' : + { + ssize_t result = read_from_file(optarg, x509_ca_pub, DTLS_PUBLIC_KEY_SIZE+1); + if (result < 0) + { + dtls_warn("Cannot read CA public key. Using default\n"); + } + else + { + x509_ca_pub_is_set = result; + } + break; + } +#endif /* DTLS_X509 */ default: usage(argv[0], dtls_package_version()); exit(1); @@ -320,6 +652,23 @@ main(int argc, char **argv) { dtls_set_log_level(log_level); +#ifdef DTLS_X509 + if (x509_server_cert_len && x509_server_priv_is_set && x509_ca_pub_is_set) + { + x509_info_from_file = 1; + } + else if(!(x509_server_cert_len || x509_server_priv_is_set || x509_ca_pub_is_set)) + { + x509_info_from_file = 0; + } + else + { + fprintf(stderr,"please set -x, -r, -u options simultaneously"); + usage(argv[0], dtls_package_version()); + exit(1); + } +#endif /* DTLS_X509 */ + /* init socket and set it to non-blocking */ fd = socket(listen_addr.sin6_family, SOCK_DGRAM, 0); @@ -328,7 +677,7 @@ main(int argc, char **argv) { return 0; } - if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on) ) < 0) { + if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, OPTVAL_T(&on), sizeof(on) ) < 0) { dtls_alert("setsockopt SO_REUSEADDR: %s\n", strerror(errno)); } #if 0 @@ -340,9 +689,9 @@ main(int argc, char **argv) { #endif on = 1; #ifdef IPV6_RECVPKTINFO - if (setsockopt(fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &on, sizeof(on) ) < 0) { + if (setsockopt(fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, OPTVAL_T(&on), sizeof(on) ) < 0) { #else /* IPV6_RECVPKTINFO */ - if (setsockopt(fd, IPPROTO_IPV6, IPV6_PKTINFO, &on, sizeof(on) ) < 0) { + if (setsockopt(fd, IPPROTO_IPV6, IPV6_PKTINFO, OPTVAL_T(&on), sizeof(on) ) < 0) { #endif /* IPV6_RECVPKTINFO */ dtls_alert("setsockopt IPV6_PKTINFO: %s\n", strerror(errno)); } @@ -356,7 +705,7 @@ main(int argc, char **argv) { the_context = dtls_new_context(&fd); - /* enable/disable tls_ecdh_anon_with_aes_128_cbc_sha */ + /* enable/disable tls_ecdh_anon_with_aes_128_cbc_sha_256 */ dtls_enables_anon_ecdh(the_context, ecdh_anon_enalbe); dtls_set_handler(the_context, &cb);