Guest User

Untitled

a guest
Jun 28th, 2015
282
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 10.62 KB | None | 0 0
  1. /*
  2.  
  3.     Create server/client self-signed certificate/key (self signed, DONT ADD PASSWORD)
  4.  
  5.     openssl req -x509 -newkey rsa:2048 -days 3650 -nodes -keyout client-key.pem -out client-cert.pem
  6.     openssl req -x509 -newkey rsa:2048 -days 3650 -nodes -keyout server-key.pem -out server-cert.pem
  7.  
  8. */
  9.  
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include <pthread.h>
  13. #include <unistd.h>
  14. #include <openssl/err.h>
  15. #include <openssl/dh.h>
  16. #include <openssl/ssl.h>
  17. #include <openssl/conf.h>
  18. #include <openssl/engine.h>
  19.  
  20. /* SSL debug */
  21. #define SSL_WHERE_INFO(ssl, w, flag, msg) {                \
  22.     if(w & flag) {                                         \
  23.       printf("+ %s: ", name);                              \
  24.       printf("%20.20s", msg);                              \
  25.       printf(" - %30.30s ", SSL_state_string_long(ssl));   \
  26.       printf(" - %5.10s ", SSL_state_string(ssl));         \
  27.       printf("\n");                                        \
  28.     }                                                      \
  29.   }
  30.  
  31. typedef void(*info_callback)();
  32.  
  33. typedef struct {
  34.   SSL_CTX* ctx;                                                                       /* main ssl context */
  35.   SSL* ssl;                                                                           /* the SSL* which represents a "connection" */
  36.   BIO* in_bio;                                                                        /* we use memory read bios */
  37.   BIO* out_bio;                                                                       /* we use memory write bios */
  38.   char name[512];
  39. } krx;
  40.  
  41. void krx_begin();                                                                     /* initialize SSL */
  42. void krx_end();                                                                       /* shutdown SSL */
  43. int krx_ssl_ctx_init(krx* k, const char* keyname);                                    /* initialize the SSL_CTX */
  44. int krx_ssl_init(krx* k, int isserver, info_callback cb);                             /* init the SSL* (the "connection"). we use the `isserver` to tell SSL that it should either use the server or client protocol */
  45. int krx_ssl_shutdown(krx* k);                                                         /* cleanup SSL allocated mem */
  46. int krx_ssl_verify_peer(int ok, X509_STORE_CTX* ctx);                                 /* we set the SSL_VERIFY_PEER option on the SSL_CTX, so that the server will request the client certificate. We can use the certificate to get/verify the fingerprint */
  47. int krx_ssl_handle_traffic(krx* from, krx* to);
  48.  
  49. /* some debug info */
  50. void krx_ssl_server_info_callback(const SSL* ssl, int where, int ret);                /* purely for debug purposes; logs server info. */
  51. void krx_ssl_client_info_callback(const SSL* ssl, int where, int ret);                /* client info callback */
  52. void krx_ssl_info_callback(const SSL* ssl, int where, int ret, const char* name);     /* generic info callback */
  53.  
  54. void* iceCompleteMockThreadCB(void *arg)
  55. {  
  56.     printf("StefanTest\n");
  57.     SSL* ssl = (SSL*) arg;
  58.     int res=SSL_is_init_finished(ssl);
  59.     printf("StefanTest 2\n");
  60.     if (SSL_is_init_finished(ssl)) {   
  61.         SSL_clear(ssl);
  62.         SSL_set_accept_state(ssl);
  63.     }
  64.     printf("StefanTest 3\n");
  65.     SSL_do_handshake(ssl);
  66.     printf("StefanTest 4\n");  
  67. }
  68.  
  69.  
  70. int main() {
  71.  
  72.   /* startup SSL */
  73.   krx_begin();
  74.  
  75.   /* create client/server objects */
  76.   krx server;
  77.   krx client;
  78.  
  79.   /* init server. */
  80.   if(krx_ssl_ctx_init(&server, "server") < 0) {
  81.     exit(EXIT_FAILURE);
  82.   }
  83.   if(krx_ssl_init(&server, 1, krx_ssl_server_info_callback) < 0) {
  84.     exit(EXIT_FAILURE);
  85.   }
  86.  
  87.   printf("+ Initialized server.\n");
  88.  
  89.   /* init client. */
  90.   if(krx_ssl_ctx_init(&client, "client") < 0) {
  91.     exit(EXIT_FAILURE);
  92.   }
  93.   if(krx_ssl_init(&client, 0, krx_ssl_client_info_callback) < 0) {
  94.     exit(EXIT_FAILURE);
  95.   }
  96.  
  97.   printf("+ Initialized client.\n");
  98.  
  99.   printf("+ creating new thread corresponding to the asterisk-thread calling ascreating new thread corresponding to the asterisk-thread calling ast_rtp_on_ice_comlete\n");
  100.   pthread_t tid[2];
  101.   int err = pthread_create(&(tid[0]), NULL, &iceCompleteMockThreadCB, server.ssl);
  102.  
  103.   /* kickoff handshake; initiated by client (e.g. browser) */
  104.   SSL_do_handshake(client.ssl);
  105.   printf("++ kickoff SSL_do_handshake returned on client.ssl.\n");
  106.   krx_ssl_handle_traffic(&client, &server);
  107.   printf("++ handle_traffic(&client, &server) returned\n");
  108.   krx_ssl_handle_traffic(&server, &client);
  109.   printf("++ handle_traffic(&server, &client) returned\n");
  110.   krx_ssl_handle_traffic(&client, &server);
  111.   printf("++ handle_traffic(&client, &server) returned\n");
  112.   krx_ssl_handle_traffic(&server, &client);
  113.   printf("++ handle_traffic(&server, &client) returned\n");
  114.  
  115. printf("++++++++ handle_traffic(&server, &client) returned HANDHSAKE should be done\n");  
  116.   /* encrypt some data and send it to the client */
  117.   char buf[521] = { 0 } ;
  118.   sprintf(buf, "%s", "Hello world");
  119.   //sleep(3);
  120.   SSL_write(server.ssl, buf, sizeof(buf));
  121.   krx_ssl_handle_traffic(&server, &client);
  122.  
  123.   krx_ssl_shutdown(&server);
  124.   krx_ssl_shutdown(&client);
  125.  
  126.   krx_end();
  127.  
  128.   return EXIT_SUCCESS;
  129. }
  130.  
  131. void krx_begin() {
  132.   SSL_library_init();
  133.   SSL_load_error_strings();
  134.   ERR_load_BIO_strings();
  135.   OpenSSL_add_all_algorithms();
  136. }
  137.  
  138. void krx_end() {
  139.   ERR_remove_state(0);
  140.   ENGINE_cleanup();
  141.   CONF_modules_unload(1);
  142.   ERR_free_strings();
  143.   EVP_cleanup();
  144.   sk_SSL_COMP_free(SSL_COMP_get_compression_methods());
  145.   CRYPTO_cleanup_all_ex_data();
  146. }
  147.  
  148. int krx_ssl_ctx_init(krx* k, const char* keyname) {
  149.  
  150.   int r = 0;
  151.  
  152.   /* create a new context using DTLS */
  153.   k->ctx = SSL_CTX_new(DTLSv1_method());
  154.  
  155.   SSL_CTX_set_read_ahead(k->ctx, 1);     
  156.   if(!k->ctx) {
  157.     printf("Error: cannot create SSL_CTX.\n");
  158.     ERR_print_errors_fp(stderr);
  159.     return -1;
  160.   }
  161.  
  162.   /* set our supported ciphers */
  163.   r = SSL_CTX_set_cipher_list(k->ctx, "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
  164.   if(r != 1) {
  165.     printf("Error: cannot set the cipher list.\n");
  166.     ERR_print_errors_fp(stderr);
  167.     return -2;
  168.   }
  169.  
  170.   /* the client doesn't have to send it's certificate */
  171.   SSL_CTX_set_verify(k->ctx, SSL_VERIFY_PEER, krx_ssl_verify_peer);
  172.  
  173.   /* enable srtp */
  174.   r = SSL_CTX_set_tlsext_use_srtp(k->ctx, "SRTP_AES128_CM_SHA1_80");
  175.   if(r != 0) {
  176.     printf("Error: cannot setup srtp.\n");
  177.     ERR_print_errors_fp(stderr);
  178.     return -3;
  179.   }
  180.  
  181.   /* load key and certificate */
  182.   char certfile[1024];
  183.   char keyfile[1024];
  184.   sprintf(certfile, "./%s-cert.pem", keyname);
  185.   sprintf(keyfile, "./%s-key.pem", keyname);
  186.  
  187.   /* certificate file; contains also the public key */
  188.   r = SSL_CTX_use_certificate_file(k->ctx, certfile, SSL_FILETYPE_PEM);
  189.   if(r != 1) {
  190.     printf("Error: cannot load certificate file.\n");
  191.     ERR_print_errors_fp(stderr);
  192.     return -4;
  193.   }
  194.  
  195.   /* load private key */
  196.   r = SSL_CTX_use_PrivateKey_file(k->ctx, keyfile, SSL_FILETYPE_PEM);
  197.   if(r != 1) {
  198.     printf("Error: cannot load private key file.\n");
  199.     ERR_print_errors_fp(stderr);
  200.     return -5;
  201.   }
  202.  
  203.   /* check if the private key is valid */
  204.   r = SSL_CTX_check_private_key(k->ctx);
  205.   if(r != 1) {
  206.     printf("Error: checking the private key failed. \n");
  207.     ERR_print_errors_fp(stderr);
  208.     return -6;
  209.   }
  210.  
  211.   sprintf(k->name, "+ %s", keyname);
  212.  
  213.   return 0;
  214. }
  215.  
  216. int krx_ssl_verify_peer(int ok, X509_STORE_CTX* ctx) {
  217.   return 1;
  218. }
  219.  
  220. /* this sets up the SSL* */
  221. int krx_ssl_init(krx* k, int isserver, info_callback cb) {
  222.  
  223.   /* create SSL* */
  224.   k->ssl = SSL_new(k->ctx);
  225.   if(!k->ssl) {
  226.     printf("Error: cannot create new SSL*.\n");
  227.     return -1;
  228.   }
  229.  
  230.   /* info callback */
  231.   SSL_set_info_callback(k->ssl, cb);
  232.  
  233.   /* bios */
  234.   k->in_bio = BIO_new(BIO_s_mem());
  235.   if(k->in_bio == NULL) {
  236.     printf("Error: cannot allocate read bio.\n");
  237.     return -2;
  238.   }
  239.  
  240.   BIO_set_mem_eof_return(k->in_bio, -1); /* see: https://www.openssl.org/docs/crypto/BIO_s_mem.html */
  241.  
  242.   k->out_bio = BIO_new(BIO_s_mem());
  243.   if(k->out_bio == NULL) {
  244.     printf("Error: cannot allocate write bio.\n");
  245.     return -3;
  246.   }
  247.  
  248.   BIO_set_mem_eof_return(k->out_bio, -1); /* see: https://www.openssl.org/docs/crypto/BIO_s_mem.html */
  249.  
  250.   SSL_set_bio(k->ssl, k->in_bio, k->out_bio);
  251.  
  252.   /* either use the server or client part of the protocol */
  253.   if(isserver == 1) {
  254.     SSL_set_accept_state(k->ssl);
  255.   }
  256.   else {
  257.     SSL_set_connect_state(k->ssl);
  258.   }
  259.  
  260.   return 0;
  261. }
  262.  
  263. void krx_ssl_server_info_callback(const SSL* ssl, int where, int ret) {
  264.   krx_ssl_info_callback(ssl, where, ret, "server");
  265. }
  266. void krx_ssl_client_info_callback(const SSL* ssl, int where, int ret) {
  267.   krx_ssl_info_callback(ssl, where, ret, "client");
  268. }
  269.  
  270. void krx_ssl_info_callback(const SSL* ssl, int where, int ret, const char* name) {
  271.  
  272.   if(ret == 0) {
  273.     printf("-- krx_ssl_info_callback: error occured.\n");
  274.     return;
  275.   }
  276.   SSL_WHERE_INFO(ssl, where, SSL_CB_EXIT, "EXIT");
  277.   SSL_WHERE_INFO(ssl, where, SSL_CB_READ, "READ");
  278.   SSL_WHERE_INFO(ssl, where, SSL_CB_WRITE, "WRITE");
  279.   SSL_WHERE_INFO(ssl, where, SSL_CB_ALERT, "ALERT");
  280.   SSL_WHERE_INFO(ssl, where, SSL_CB_LOOP, "LOOP");
  281.   SSL_WHERE_INFO(ssl, where, SSL_CB_HANDSHAKE_START, "HANDSHAKE START");
  282.   SSL_WHERE_INFO(ssl, where, SSL_CB_HANDSHAKE_DONE, "HANDSHAKE DONE");
  283. }
  284.  
  285. int krx_ssl_handle_traffic(krx* from, krx* to) {
  286.  
  287.   // Did SSL write something into the out buffer
  288.   char outbuf[4096];
  289.   int written = 0;
  290.   int read = 0;
  291.   int pending = BIO_ctrl_pending(from->out_bio);
  292.  
  293.   if(pending > 0) {
  294.     read = BIO_read(from->out_bio, outbuf, sizeof(outbuf));
  295.   }
  296.  
  297.   if(read > 0) {
  298.     written = BIO_write(to->in_bio, outbuf, read);
  299.   }
  300.  
  301.  
  302.   printf("%s Pending %d, and read: %d and written: %d \n", from->name, pending, read,written);
  303.   if(written > 0) {
  304.     if(!SSL_is_init_finished(to->ssl)) {
  305.       int res = SSL_read(to->ssl, outbuf, sizeof(outbuf));      
  306.       // int res=SSL_do_handshake(to->ssl);
  307.       printf("SSL_is_init_finished is false, return value of SSL_read (or SSL_do_handshake is %d \n",res);
  308.       if (res<=0) {
  309.     res = SSL_get_error(to->ssl, res);
  310.     if (res == SSL_ERROR_WANT_READ) {
  311.         printf("err: SSL_ERROR_WANT_READ \n");
  312.     } else if (res == SSL_ERROR_WANT_WRITE) {
  313.         printf("err: SSL_ERROR_WANT_WRITE \n");
  314.     } else {
  315.         printf("err: UNKNOWN \n");
  316.         }
  317.       }
  318.     } else {
  319.       read = SSL_read(to->ssl, outbuf, sizeof(outbuf));
  320.       printf("%s read: %s\n", to->name, outbuf);
  321.     }
  322.   }
  323.  
  324.   return 0;
  325. }
  326.  
  327. int krx_ssl_shutdown(krx* k) {
  328.   if(!k) {
  329.     return -1;
  330.   }
  331.  
  332.   if(k->ctx) {
  333.     SSL_CTX_free(k->ctx);
  334.     k->ctx = NULL;
  335.   }
  336.  
  337.   if(k->ssl) {
  338.     SSL_free(k->ssl);
  339.     k->ssl = NULL;
  340.   }
  341.  
  342.   return 0;
  343. }
Advertisement
Add Comment
Please, Sign In to add comment