{"id":23,"date":"2007-09-22T19:55:34","date_gmt":"2007-09-23T02:55:34","guid":{"rendered":"http:\/\/www.kernelcrash.com\/blog\/2007\/09\/22\/converting-a-tcp-client-program-to-ssl\/"},"modified":"2007-09-25T00:01:13","modified_gmt":"2007-09-25T07:01:13","slug":"converting-a-tcp-client-program-to-ssl","status":"publish","type":"post","link":"https:\/\/www.kernelcrash.com\/blog\/converting-a-tcp-client-program-to-ssl\/2007\/09\/22\/","title":{"rendered":"Converting a tcp client program to SSL"},"content":{"rendered":"<p>Recently I updated a usenet client program I&#8217;d written to use SSL. The usenet NNTP protocol has been around for a very long time, and is a very simple text based protocol. The program I had is written in C and simply opens a tcp client socket to an NNTP server, promotes the socked to a file descriptor then uses fgets and fputs to send lines back and forth. Its pretty elementary stuff.<\/p>\n<p>Now, in recent years usenet server have started handling requests via NNTPS, or NNTP over SSL. I hadn&#8217;t considered updating my program to use SSL, but my brother wanted to use it in this way, so I started to investigate how to update it.<\/p>\n<p>OpenSSL is the usual library to use, so I started searching for examples of how to use it. Initially I thought I could just replace the connect with an SSL equivalent and also somehow promote my ssl socket so I could use fgets\/fputs on it. Not so. It was a little more complicated than that<\/p>\n<p>First there is a lot more initialisation code: (apologies for the indentation. I hate wordpress)<\/p>\n<pre>\r\nSSL_library_init(); \r\nSSL_load_error_strings(); \r\nOpenSSL_add_all_algorithms(); \r\nCRYPTO_set_id_callback(thread_id_myprog); \r\nCRYPTO_set_locking_callback(thread_lock_myprog); \r\nnum_locks = CRYPTO_num_locks(); \r\nlocks = malloc (num_locks * sizeof *locks); \r\nfor (n=0;n &lt; num_locks;n++) { \r\n   if (pthread_mutex_init(&amp;locks[n], NULL)) { \r\n      printf(&#34;cannot init mutexes for openssl&#92;n&#34;); \r\n      return -1; \r\n   } \r\n}<\/pre>\n<p>All the locks stuff is supposedly to do with my program being multi-threaded. I don&#8217;t really understand it that well.<\/p>\n<p>Then you need to make your tcp client socket connection as you normally do (in the &#8216;sock&#8217; var below)<\/p>\n<pre>\r\nint sock; \r\n\r\nSSL_CTX *context; \r\nSSL_METHOD *method; \r\nSSL *connection; \r\nBIO *io; \r\nBIO *sbio; \r\nBIO *ssl_bio; \r\n\r\ncontext= NULL; \r\nmethod= NULL; \r\nconnection=NULL; \r\nmethod=SSLv23_client_method(); \r\ncontext = SSL_CTX_new(connection.method); \r\n... \r\nsbio= BIO_new_socket(sock,BIO_NOCLOSE); \r\nif (sbio==NULL) {printf(\"bad sbion\"); exit(1); } \r\nconnection = SSL_new(context); \r\nif (connection==NULL) {printf(\"bad connectionn\"); exit(1); } \r\nSSL_set_bio(connection,sbio,sbio); \r\n... \r\nio = BIO_new(BIO_f_buffer()); \r\nssl_bio = BIO_new(BIO_f_ssl()); \r\nBIO_set_ssl(ssl_bio,connection,BIO_CLOSE); \r\nBIO_push(io,ssl_bio); \r\n... \r\nSSL_connect(connection);<\/pre>\n<p>Thats enought to get the SSL connection going. You&#8217;ll find examples similar to the above all over the place (i find <a HREF=\"http:\/\/www.google.com\/codesearch\">Google codesearch<\/a> invaluable). I think you&#8217;re meant to verify the SSL cert somewhere in there as well.<\/p>\n<p>And now for the bit that tripped me up. Initially I made attempts to use SSL_read to read lines from the remote NNTPS server. SSL_read works much the same as read so its not line buffered. I really needed a line buffered function, otherwise I&#8217;d have to do a lot of rewriting. Fortunately there are some line buffered functions; the BIO functions. So my fgets was basically replaced with:<\/p>\n<pre>\r\nresult = BIO_gets(io,linebuf,sizeof(linebuf));\r\n<\/pre>\n<p>My fputs was replaced with:<\/p>\n<pre>\r\nBIO_puts(io,cmdbuf); \r\nBIO_flush(io);<\/pre>\n<p>And finally when you&#8217;re closing your connection you need to do this:<\/p>\n<pre>\r\nSSL_set_shutdown(connection, \r\n   SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN); \r\nBIO_free_all(io);<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Recently I updated a usenet client program I&#8217;d written to use SSL. The usenet NNTP protocol has been around for a very long time, and is a very simple text based protocol. The program I had is written in C and simply opens a tcp client socket to an NNTP server, promotes the socked to [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3],"tags":[],"class_list":["post-23","post","type-post","status-publish","format-standard","hentry","category-linux"],"_links":{"self":[{"href":"https:\/\/www.kernelcrash.com\/blog\/wp-json\/wp\/v2\/posts\/23","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.kernelcrash.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.kernelcrash.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.kernelcrash.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.kernelcrash.com\/blog\/wp-json\/wp\/v2\/comments?post=23"}],"version-history":[{"count":0,"href":"https:\/\/www.kernelcrash.com\/blog\/wp-json\/wp\/v2\/posts\/23\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.kernelcrash.com\/blog\/wp-json\/wp\/v2\/media?parent=23"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.kernelcrash.com\/blog\/wp-json\/wp\/v2\/categories?post=23"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.kernelcrash.com\/blog\/wp-json\/wp\/v2\/tags?post=23"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}