testget.c 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348
  1. #include <sys/socket.h>
  2. #include <sys/types.h>
  3. #include <netinet/in.h>
  4. #include <netdb.h>
  5. #include <stdio.h>
  6. #include <string.h>
  7. #include <stdlib.h>
  8. #include <unistd.h>
  9. #include <errno.h>
  10. #include <openssl/rand.h>
  11. #include <openssl/ssl.h>
  12. #include <openssl/err.h>
  13. #include "ptwist.h"
  14. #include "rclient.h"
  15. /* Copied from ssl_locl.h */
  16. # define l2n(l,c) (*((c)++)=(unsigned char)(((l)>>24)&0xff), \
  17. *((c)++)=(unsigned char)(((l)>>16)&0xff), \
  18. *((c)++)=(unsigned char)(((l)>> 8)&0xff), \
  19. *((c)++)=(unsigned char)(((l) )&0xff))
  20. // Simple structure to keep track of the handle, and
  21. // of what needs to be freed later.
  22. typedef struct {
  23. int socket;
  24. SSL *sslHandle;
  25. SSL_CTX *sslContext;
  26. } connection;
  27. int generate_backdoor_key(SSL *s, DH *dh);
  28. // For this example, we'll be testing on openssl.org
  29. #define SERVER "cs.uwaterloo.ca"
  30. #define PORT 443
  31. byte key[16];
  32. //Client hello callback
  33. int tag_flow(SSL *s){
  34. unsigned char *result;
  35. int len;
  36. result = s->s3->client_random;
  37. len = sizeof(s->s3->client_random);
  38. if(len < PTWIST_TAG_BYTES) {
  39. printf("Uhoh\n");
  40. return 1;
  41. }
  42. //send_time = (s->mode & SSL_MODE_SEND_CLIENTHELLO_TIME) != 0;
  43. //if (send_time) {
  44. unsigned long Time = (unsigned long)time(NULL);
  45. unsigned char *p = result;
  46. l2n(Time, p);
  47. tag_hello((byte *) result+4, key);
  48. printf("Hello tagged.\n");
  49. //} else {
  50. // printf("hmm\n");
  51. // tag_hello((byte *) result);
  52. //}
  53. return 0;
  54. }
  55. // Establish a regular tcp connection
  56. int tcpConnect ()
  57. {
  58. int error, handle;
  59. struct hostent *host;
  60. struct sockaddr_in server;
  61. host = gethostbyname (SERVER);
  62. handle = socket (AF_INET, SOCK_STREAM, 0);
  63. if (handle == -1)
  64. {
  65. perror ("Socket");
  66. handle = 0;
  67. }
  68. else
  69. {
  70. server.sin_family = AF_INET;
  71. server.sin_port = htons (PORT);
  72. server.sin_addr = *((struct in_addr *) host->h_addr);
  73. bzero (&(server.sin_zero), 8);
  74. error = connect (handle, (struct sockaddr *) &server,
  75. sizeof (struct sockaddr));
  76. if (error == -1)
  77. {
  78. perror ("Connect");
  79. handle = 0;
  80. }
  81. }
  82. return handle;
  83. }
  84. // Establish a connection using an SSL layer
  85. connection *sslConnect (void)
  86. {
  87. connection *c;
  88. FILE *fp;
  89. c = malloc (sizeof (connection));
  90. c->sslHandle = NULL;
  91. c->sslContext = NULL;
  92. c->socket = tcpConnect ();
  93. if (c->socket)
  94. {
  95. // Register the error strings for libcrypto & libssl
  96. SSL_load_error_strings();
  97. // Register the available ciphers and digests
  98. SSL_library_init();
  99. // New context saying we are a client, and using TLSv1.2
  100. c->sslContext = SSL_CTX_new (TLSv1_2_method());
  101. //Tag the client hello message with Telex tag
  102. SSL_CTX_set_client_hello_callback(c->sslContext, tag_flow);
  103. //Set backdoored DH callback
  104. SSL_CTX_set_generate_key_callback(c->sslContext, generate_backdoor_key);
  105. if (c->sslContext == NULL)
  106. ERR_print_errors_fp (stderr);
  107. //make sure DH is in the cipher list
  108. const char *ciphers = "DH";
  109. if(!SSL_CTX_set_cipher_list(c->sslContext, ciphers))
  110. printf("Failed to set cipher.\n");
  111. // Create an SSL struct for the connection
  112. c->sslHandle = SSL_new (c->sslContext);
  113. if (c->sslHandle == NULL)
  114. ERR_print_errors_fp (stderr);
  115. const unsigned char *list = SSL_get_cipher_list(c->sslHandle, 1);
  116. printf("List of ciphers: %s", list);
  117. // Connect the SSL struct to our connection
  118. if (!SSL_set_fd (c->sslHandle, c->socket))
  119. ERR_print_errors_fp (stderr);
  120. // Initiate SSL handshake
  121. if (SSL_connect (c->sslHandle) != 1)
  122. ERR_print_errors_fp (stderr);
  123. }
  124. else
  125. {
  126. perror ("Connect failed");
  127. }
  128. return c;
  129. }
  130. // Disconnect & free connection struct
  131. void sslDisconnect (connection *c)
  132. {
  133. if (c->socket)
  134. close (c->socket);
  135. if (c->sslHandle)
  136. {
  137. SSL_shutdown (c->sslHandle);
  138. SSL_free (c->sslHandle);
  139. }
  140. if (c->sslContext)
  141. SSL_CTX_free (c->sslContext);
  142. free (c);
  143. }
  144. // Read all available text from the connection
  145. char *sslRead (connection *c)
  146. {
  147. const int readSize = 1024;
  148. char *rc = NULL;
  149. int received, count = 0;
  150. char buffer[1024];
  151. if (c)
  152. {
  153. while (1)
  154. {
  155. if (!rc)
  156. rc = malloc (readSize * sizeof (char) + 1);
  157. else
  158. rc = realloc (rc, (count + 1) *
  159. readSize * sizeof (char) + 1);
  160. received = SSL_read (c->sslHandle, buffer, readSize);
  161. buffer[received] = '\0';
  162. if (received > 0)
  163. strcat (rc, buffer);
  164. if (received < readSize)
  165. break;
  166. count++;
  167. }
  168. }
  169. return rc;
  170. }
  171. // Write text to the connection
  172. void sslWrite (connection *c, char *text)
  173. {
  174. if (c)
  175. SSL_write (c->sslHandle, text, strlen (text));
  176. printf("Wrote:\n%s\n", text);
  177. }
  178. // Very basic main: we send GET / and print the response.
  179. int main (int argc, char **argv)
  180. {
  181. connection *c;
  182. char *response;
  183. c = sslConnect ();
  184. sslWrite (c, "GET /index.php HTTP/1.1\r\nhost: cs.uwaterloo.ca\r\n\r\n");
  185. response = sslRead (c);
  186. printf ("%s\n", response);
  187. sslDisconnect (c);
  188. free (response);
  189. return 0;
  190. }
  191. //dh callback
  192. int generate_backdoor_key(SSL *s, DH *dh)
  193. {
  194. int ok = 0;
  195. int generate_new_key = 0;
  196. unsigned l;
  197. BN_CTX *ctx;
  198. BN_MONT_CTX *mont = NULL;
  199. BIGNUM *pub_key = NULL, *priv_key= NULL;
  200. unsigned char *buf, *seed;
  201. int bytes, i;
  202. FILE *fp;
  203. seed = (unsigned char *) key;
  204. fp = fopen("seed", "wb");
  205. if (fp == NULL) {
  206. perror("fopen");
  207. exit(1);
  208. }
  209. for(i=0; i< 16; i++){
  210. fprintf(fp, "%02x", key[i]);
  211. }
  212. fclose(fp);
  213. printf("In backdoor callback.\n");
  214. ctx = BN_CTX_new();
  215. if (ctx == NULL)
  216. goto err;
  217. if (dh->priv_key == NULL) {
  218. priv_key = BN_new();
  219. if (priv_key == NULL)
  220. goto err;
  221. generate_new_key = 1;
  222. } else
  223. priv_key = dh->priv_key;
  224. if (dh->pub_key == NULL) {
  225. pub_key = BN_new();
  226. if (pub_key == NULL)
  227. goto err;
  228. } else
  229. pub_key = dh->pub_key;
  230. if (dh->flags & DH_FLAG_CACHE_MONT_P) {
  231. mont = BN_MONT_CTX_set_locked(&dh->method_mont_p,
  232. CRYPTO_LOCK_DH, dh->p, ctx);
  233. if (!mont)
  234. goto err;
  235. }
  236. if (generate_new_key) {
  237. /* secret exponent length */
  238. l = dh->length ? dh->length : BN_num_bits(dh->p) - 1;
  239. bytes = (l+7) / 8;
  240. /* set exponent to seeded prg value */
  241. buf = (unsigned char *)OPENSSL_malloc(bytes);
  242. if (buf == NULL){
  243. BNerr(BN_F_BNRAND, ERR_R_MALLOC_FAILURE);
  244. goto err;
  245. }
  246. RAND_seed(seed, 16);
  247. if(RAND_bytes(buf, bytes) <= 0)
  248. goto err;
  249. //printf("Generated the following rand bytes: ");
  250. //for(i=0; i< bytes; i++){
  251. // printf(" %02x ", buf[i]);
  252. //}
  253. //printf("\n");
  254. if (!BN_bin2bn(buf, bytes, priv_key))
  255. goto err;
  256. }
  257. {
  258. BIGNUM local_prk;
  259. BIGNUM *prk;
  260. if ((dh->flags & DH_FLAG_NO_EXP_CONSTTIME) == 0) {
  261. BN_init(&local_prk);
  262. prk = &local_prk;
  263. BN_with_flags(prk, priv_key, BN_FLG_CONSTTIME);
  264. } else
  265. prk = priv_key;
  266. if (!dh->meth->bn_mod_exp(dh, pub_key, dh->g, prk, dh->p, ctx, mont))
  267. goto err;
  268. }
  269. dh->pub_key = pub_key;
  270. dh->priv_key = priv_key;
  271. ok = 1;
  272. err:
  273. if (buf != NULL){
  274. OPENSSL_cleanse(buf, bytes);
  275. OPENSSL_free(buf);
  276. }
  277. if (ok != 1)
  278. DHerr(DH_F_GENERATE_KEY, ERR_R_BN_LIB);
  279. if ((pub_key != NULL) && (dh->pub_key == NULL))
  280. BN_free(pub_key);
  281. if ((priv_key != NULL) && (dh->priv_key == NULL))
  282. BN_free(priv_key);
  283. BN_CTX_free(ctx);
  284. return (ok);
  285. }