Merge pull request #275 from huitema/bcrypt-on-windows

Bcrypt on windows
diff --git a/.travis.yml b/.travis.yml
index 55c5417..3dbc306 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -19,16 +19,20 @@
       before_install: *bs_linux
     - name: macOS (Xcode)
       os: osx
+      addons: &addons_macos
+        homebrew:
+          packages:
+            - libfaketime
       env:
         - CMAKE_OPTS=" -DOPENSSL_ROOT_DIR=/usr/local/opt/openssl/"
       before_install: &bs_macos
         - curl -L https://cpanmin.us | sudo perl - App::cpanminus
         - sudo cpanm --notest Scope::Guard
         - sudo cpanm --notest Test::TCP
-        - brew install libfaketime
     - name: macOS (Xcode 10.1/clang-10)
       os: osx
       osx_image: xcode10.1
+      addons: *addons_macos
       env:
         - CMAKE_OPTS=" -DOPENSSL_ROOT_DIR=/usr/local/opt/openssl/"
       before_install: *bs_macos
diff --git a/include/picotls.h b/include/picotls.h
index 4181714..84ad57a 100644
--- a/include/picotls.h
+++ b/include/picotls.h
@@ -967,10 +967,17 @@
     } while (0)
 
 /**
- * create a object to handle new TLS connection. Client-side of a TLS connection is created if server_name is non-NULL. Otherwise,
- * a server-side connection is created.
+ * create a client object to handle new TLS connection
  */
-ptls_t *ptls_new(ptls_context_t *ctx, int is_server);
+ptls_t *ptls_client_new(ptls_context_t *ctx);
+/**
+ * create a server object to handle new TLS connection
+ */
+ptls_t *ptls_server_new(ptls_context_t *ctx);
+/**
+ * creates a object handle new TLS connection
+ */
+static ptls_t *ptls_new(ptls_context_t *ctx, int is_server);
 /**
  * releases all resources associated to the object
  */
@@ -1107,7 +1114,9 @@
  */
 static void ptls_cipher_init(ptls_cipher_context_t *ctx, const void *iv);
 /**
- * encrypts given text
+ * Encrypts given text. The function must be used in a way that the output length would be equal to the input length. For example,
+ * when using a block cipher in ECB mode, `len` must be a multiple of the block size when using a block cipher. The length can be
+ * of any value when using a stream cipher or a block cipher in CTR mode.
  */
 static void ptls_cipher_encrypt(ptls_cipher_context_t *ctx, void *output, const void *input, size_t len);
 /**
@@ -1172,6 +1181,10 @@
  */
 int ptls_handle_message(ptls_t *tls, ptls_buffer_t *sendbuf, size_t epoch_offsets[5], size_t in_epoch, const void *input,
                         size_t inlen, ptls_handshake_properties_t *properties);
+int ptls_client_handle_message(ptls_t *tls, ptls_buffer_t *sendbuf, size_t epoch_offsets[5], size_t in_epoch, const void *input,
+                               size_t inlen, ptls_handshake_properties_t *properties);
+int ptls_server_handle_message(ptls_t *tls, ptls_buffer_t *sendbuf, size_t epoch_offsets[5], size_t in_epoch, const void *input,
+                               size_t inlen, ptls_handshake_properties_t *properties);
 /**
  * internal
  */
@@ -1233,6 +1246,11 @@
 
 /* inline functions */
 
+inline ptls_t *ptls_new(ptls_context_t *ctx, int is_server)
+{
+    return is_server ? ptls_server_new(ctx) : ptls_client_new(ctx);
+}
+
 inline ptls_iovec_t ptls_iovec_init(const void *p, size_t len)
 {
     /* avoid the "return (ptls_iovec_t){(uint8_t *)p, len};" construct because it requires C99
diff --git a/lib/picotls.c b/lib/picotls.c
index 5b4e060..afa2f34 100644
--- a/lib/picotls.c
+++ b/lib/picotls.c
@@ -471,7 +471,6 @@
 }
 #endif
 
-
 #ifndef ntoh24
 static uint32_t ntoh24(const uint8_t *src)
 {
@@ -1796,8 +1795,8 @@
     return ret;
 }
 
-static int emit_esni_extension(ptls_esni_secret_t *esni, ptls_buffer_t *buf, ptls_iovec_t esni_keys,
-                               const char *server_name, size_t key_share_ch_off, size_t key_share_ch_len)
+static int emit_esni_extension(ptls_esni_secret_t *esni, ptls_buffer_t *buf, ptls_iovec_t esni_keys, const char *server_name,
+                               size_t key_share_ch_off, size_t key_share_ch_len)
 {
     ptls_aead_context_t *aead = NULL;
     int ret;
@@ -3607,7 +3606,8 @@
             server_name = ch.server_name;
         }
         if (tls->ctx->on_client_hello != NULL) {
-            ptls_on_client_hello_parameters_t params = {server_name, message,
+            ptls_on_client_hello_parameters_t params = {server_name,
+                                                        message,
                                                         {ch.alpn.list, ch.alpn.count},
                                                         {ch.signature_algorithms.list, ch.signature_algorithms.count},
                                                         {ch.cert_compression_algos.list, ch.cert_compression_algos.count},
@@ -4131,7 +4131,7 @@
         ctx->update_open_count->cb(ctx->update_open_count, delta);
 }
 
-ptls_t *ptls_new(ptls_context_t *ctx, int is_server)
+static ptls_t *new_instance(ptls_context_t *ctx, int is_server)
 {
     ptls_t *tls;
 
@@ -4145,17 +4145,28 @@
     tls->is_server = is_server;
     tls->send_change_cipher_spec = ctx->send_change_cipher_spec;
     tls->skip_tracing = ptls_default_skip_tracing;
-    if (!is_server) {
-        tls->state = PTLS_STATE_CLIENT_HANDSHAKE_START;
-        tls->ctx->random_bytes(tls->client_random, sizeof(tls->client_random));
-        log_client_random(tls);
-        tls->ctx->random_bytes(tls->client.legacy_session_id, sizeof(tls->client.legacy_session_id));
-    } else {
-        tls->state = PTLS_STATE_SERVER_EXPECT_CLIENT_HELLO;
-        tls->server.early_data_skipped_bytes = UINT32_MAX;
-    }
+    return tls;
+}
 
-    PTLS_PROBE(NEW, tls, is_server);
+ptls_t *ptls_client_new(ptls_context_t *ctx)
+{
+    ptls_t *tls = new_instance(ctx, 0);
+    tls->state = PTLS_STATE_CLIENT_HANDSHAKE_START;
+    tls->ctx->random_bytes(tls->client_random, sizeof(tls->client_random));
+    log_client_random(tls);
+    tls->ctx->random_bytes(tls->client.legacy_session_id, sizeof(tls->client.legacy_session_id));
+
+    PTLS_PROBE(NEW, tls, 0);
+    return tls;
+}
+
+ptls_t *ptls_server_new(ptls_context_t *ctx)
+{
+    ptls_t *tls = new_instance(ctx, 1);
+    tls->state = PTLS_STATE_SERVER_EXPECT_CLIENT_HELLO;
+    tls->server.early_data_skipped_bytes = UINT32_MAX;
+
+    PTLS_PROBE(NEW, tls, 1);
     return tls;
 }
 
@@ -4291,8 +4302,8 @@
     tls->skip_tracing = skip_tracing;
 }
 
-static int handle_handshake_message(ptls_t *tls, ptls_message_emitter_t *emitter, ptls_iovec_t message, int is_end_of_record,
-                                    ptls_handshake_properties_t *properties)
+static int handle_client_handshake_message(ptls_t *tls, ptls_message_emitter_t *emitter, ptls_iovec_t message, int is_end_of_record,
+                                           ptls_handshake_properties_t *properties)
 {
     uint8_t type = message.base[0];
     int ret;
@@ -4346,6 +4357,38 @@
             ret = PTLS_ALERT_UNEXPECTED_MESSAGE;
         }
         break;
+    case PTLS_STATE_CLIENT_POST_HANDSHAKE:
+        switch (type) {
+        case PTLS_HANDSHAKE_TYPE_NEW_SESSION_TICKET:
+            ret = client_handle_new_session_ticket(tls, message);
+            break;
+        case PTLS_HANDSHAKE_TYPE_KEY_UPDATE:
+            ret = handle_key_update(tls, emitter, message);
+            break;
+        default:
+            ret = PTLS_ALERT_UNEXPECTED_MESSAGE;
+            break;
+        }
+        break;
+    default:
+        assert(!"unexpected state");
+        ret = PTLS_ALERT_INTERNAL_ERROR;
+        break;
+    }
+
+    PTLS_PROBE(RECEIVE_MESSAGE, tls, message.base[0], message.base + PTLS_HANDSHAKE_HEADER_SIZE,
+               message.len - PTLS_HANDSHAKE_HEADER_SIZE, ret);
+
+    return ret;
+}
+
+static int handle_server_handshake_message(ptls_t *tls, ptls_message_emitter_t *emitter, ptls_iovec_t message, int is_end_of_record,
+                                           ptls_handshake_properties_t *properties)
+{
+    uint8_t type = message.base[0];
+    int ret;
+
+    switch (tls->state) {
     case PTLS_STATE_SERVER_EXPECT_CLIENT_HELLO:
     case PTLS_STATE_SERVER_EXPECT_SECOND_CLIENT_HELLO:
         if (type == PTLS_HANDSHAKE_TYPE_CLIENT_HELLO && is_end_of_record) {
@@ -4383,19 +4426,6 @@
             ret = PTLS_ALERT_HANDSHAKE_FAILURE;
         }
         break;
-    case PTLS_STATE_CLIENT_POST_HANDSHAKE:
-        switch (type) {
-        case PTLS_HANDSHAKE_TYPE_NEW_SESSION_TICKET:
-            ret = client_handle_new_session_ticket(tls, message);
-            break;
-        case PTLS_HANDSHAKE_TYPE_KEY_UPDATE:
-            ret = handle_key_update(tls, emitter, message);
-            break;
-        default:
-            ret = PTLS_ALERT_UNEXPECTED_MESSAGE;
-            break;
-        }
-        break;
     case PTLS_STATE_SERVER_POST_HANDSHAKE:
         switch (type) {
         case PTLS_HANDSHAKE_TYPE_KEY_UPDATE:
@@ -4408,6 +4438,7 @@
         break;
     default:
         assert(!"unexpected state");
+        ret = PTLS_ALERT_INTERNAL_ERROR;
         break;
     }
 
@@ -4540,7 +4571,8 @@
 
     if (tls->recvbuf.mess.base != NULL || rec.type == PTLS_CONTENT_TYPE_HANDSHAKE) {
         /* handshake record */
-        ret = handle_handshake_record(tls, handle_handshake_message, emitter, &rec, properties);
+        ret = handle_handshake_record(tls, tls->is_server ? handle_server_handshake_message : handle_client_handshake_message,
+                                      emitter, &rec, properties);
     } else {
         /* handling of an alert or an application record */
         switch (rec.type) {
@@ -4577,7 +4609,7 @@
     goto NextRecord;
 }
 
-static void init_record_message_emmitter(ptls_t *tls, struct st_ptls_record_message_emitter_t *emitter, ptls_buffer_t *sendbuf)
+static void init_record_message_emitter(ptls_t *tls, struct st_ptls_record_message_emitter_t *emitter, ptls_buffer_t *sendbuf)
 {
     *emitter = (struct st_ptls_record_message_emitter_t){
         {sendbuf, &tls->traffic_protection.enc, 5, begin_record_message, commit_record_message}};
@@ -4590,7 +4622,7 @@
 
     assert(tls->state < PTLS_STATE_POST_HANDSHAKE_MIN);
 
-    init_record_message_emmitter(tls, &emitter, _sendbuf);
+    init_record_message_emitter(tls, &emitter, _sendbuf);
     size_t sendbuf_orig_off = emitter.super.buf->off;
 
     /* special handlings */
@@ -4683,7 +4715,7 @@
     struct st_ptls_record_message_emitter_t emitter;
     int ret;
 
-    init_record_message_emmitter(tls, &emitter, _sendbuf);
+    init_record_message_emitter(tls, &emitter, _sendbuf);
     size_t sendbuf_orig_off = emitter.super.buf->off;
 
     ptls_push_message(&emitter.super, NULL, PTLS_HANDSHAKE_TYPE_KEY_UPDATE,
@@ -5147,6 +5179,15 @@
 int ptls_handle_message(ptls_t *tls, ptls_buffer_t *sendbuf, size_t epoch_offsets[5], size_t in_epoch, const void *input,
                         size_t inlen, ptls_handshake_properties_t *properties)
 {
+    return tls->is_server ? ptls_server_handle_message(tls, sendbuf, epoch_offsets, in_epoch, input, inlen, properties)
+                          : ptls_client_handle_message(tls, sendbuf, epoch_offsets, in_epoch, input, inlen, properties);
+}
+
+int ptls_client_handle_message(ptls_t *tls, ptls_buffer_t *sendbuf, size_t epoch_offsets[5], size_t in_epoch, const void *input,
+                               size_t inlen, ptls_handshake_properties_t *properties)
+{
+    assert(!tls->is_server);
+
     struct st_ptls_raw_message_emitter_t emitter = {
         {sendbuf, &tls->traffic_protection.enc, 0, begin_raw_message, commit_raw_message}, SIZE_MAX, epoch_offsets};
     struct st_ptls_record_t rec = {PTLS_CONTENT_TYPE_HANDSHAKE, 0, inlen, input};
@@ -5157,7 +5198,24 @@
     if (ptls_get_read_epoch(tls) != in_epoch)
         return PTLS_ALERT_UNEXPECTED_MESSAGE;
 
-    return handle_handshake_record(tls, handle_handshake_message, &emitter.super, &rec, properties);
+    return handle_handshake_record(tls, handle_client_handshake_message, &emitter.super, &rec, properties);
+}
+
+int ptls_server_handle_message(ptls_t *tls, ptls_buffer_t *sendbuf, size_t epoch_offsets[5], size_t in_epoch, const void *input,
+                               size_t inlen, ptls_handshake_properties_t *properties)
+{
+    assert(tls->is_server);
+
+    struct st_ptls_raw_message_emitter_t emitter = {
+        {sendbuf, &tls->traffic_protection.enc, 0, begin_raw_message, commit_raw_message}, SIZE_MAX, epoch_offsets};
+    struct st_ptls_record_t rec = {PTLS_CONTENT_TYPE_HANDSHAKE, 0, inlen, input};
+
+    assert(input);
+
+    if (ptls_get_read_epoch(tls) != in_epoch)
+        return PTLS_ALERT_UNEXPECTED_MESSAGE;
+
+    return handle_handshake_record(tls, handle_server_handshake_message, &emitter.super, &rec, properties);
 }
 
 int ptls_esni_init_context(ptls_context_t *ctx, ptls_esni_context_t *esni, ptls_iovec_t esni_keys,
diff --git a/picotls.xcodeproj/project.pbxproj b/picotls.xcodeproj/project.pbxproj
index 519a807..4788870 100644
--- a/picotls.xcodeproj/project.pbxproj
+++ b/picotls.xcodeproj/project.pbxproj
@@ -96,6 +96,13 @@
 		E97577032212405D00D1EF74 /* ffx.c in Sources */ = {isa = PBXBuildFile; fileRef = E97577022212405D00D1EF74 /* ffx.c */; };
 		E97577042212407900D1EF74 /* ffx.c in Sources */ = {isa = PBXBuildFile; fileRef = E97577022212405D00D1EF74 /* ffx.c */; };
 		E97577052212407900D1EF74 /* ffx.c in Sources */ = {isa = PBXBuildFile; fileRef = E97577022212405D00D1EF74 /* ffx.c */; };
+		E9925A122354C37500CA2082 /* picotls-probes.d in Sources */ = {isa = PBXBuildFile; fileRef = E95EBCC0227B71170022C32D /* picotls-probes.d */; };
+		E9925A132354C37600CA2082 /* picotls-probes.d in Sources */ = {isa = PBXBuildFile; fileRef = E95EBCC0227B71170022C32D /* picotls-probes.d */; };
+		E9925A142354C3CF00CA2082 /* aes128.c in Sources */ = {isa = PBXBuildFile; fileRef = E9F20BE222E34B340018D260 /* aes128.c */; };
+		E9925A152354C3DC00CA2082 /* aes256.c in Sources */ = {isa = PBXBuildFile; fileRef = E9F20BE022E34B340018D260 /* aes256.c */; };
+		E9925A162354C3DF00CA2082 /* chacha20.c in Sources */ = {isa = PBXBuildFile; fileRef = E9F20BE422E34B340018D260 /* chacha20.c */; };
+		E9925A172354C3E200CA2082 /* random.c in Sources */ = {isa = PBXBuildFile; fileRef = E9F20BF922E34C110018D260 /* random.c */; };
+		E9925A182354C3E500CA2082 /* x25519.c in Sources */ = {isa = PBXBuildFile; fileRef = E9F20BE122E34B340018D260 /* x25519.c */; };
 		E992F7A320E99A7C0008154D /* libpicotls-openssl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1059008C1DC8E1A300FB4085 /* libpicotls-openssl.a */; };
 		E992F7A420E99A7C0008154D /* libpicotls-core.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 106530DA1D9B3E6F005B2C60 /* libpicotls-core.a */; };
 		E992F7AA20E99AA10008154D /* esni.c in Sources */ = {isa = PBXBuildFile; fileRef = E992F79A20E99A6B0008154D /* esni.c */; };
@@ -764,6 +771,7 @@
 			isa = PBXSourcesBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
+				E9925A132354C37600CA2082 /* picotls-probes.d in Sources */,
 				105900B61DC943D400FB4085 /* aes.c in Sources */,
 				E99B75E51F5CE64E00CF503E /* pembase64.c in Sources */,
 				E97577052212407900D1EF74 /* ffx.c in Sources */,
@@ -807,19 +815,25 @@
 				E97577042212407900D1EF74 /* ffx.c in Sources */,
 				E9BC76E01EF3CCDD00EB7A09 /* poly1305.c in Sources */,
 				105900CF1DCBECFB00FB4085 /* modes.c in Sources */,
+				E9925A122354C37500CA2082 /* picotls-probes.d in Sources */,
 				106530EA1D9B7C13005B2C60 /* picotls.c in Sources */,
+				E9925A142354C3CF00CA2082 /* aes128.c in Sources */,
 				105900CD1DCBECF400FB4085 /* gcm.c in Sources */,
 				E9E865EC203BD46600E2FFCD /* sha512.c in Sources */,
 				105900D01DCBECFE00FB4085 /* sha256.c in Sources */,
 				1059004C1DC8D5B700FB4085 /* openssl.c in Sources */,
 				105900D21DCBED0A00FB4085 /* uecc.c in Sources */,
+				E9925A182354C3E500CA2082 /* x25519.c in Sources */,
 				E99B75E21F5CE54D00CF503E /* asn1.c in Sources */,
 				105900C81DCBECDD00FB4085 /* blockwise.c in Sources */,
+				E9925A172354C3E200CA2082 /* random.c in Sources */,
 				105900D31DCBED1D00FB4085 /* uECC.c in Sources */,
 				105900C91DCBECE100FB4085 /* chash.c in Sources */,
+				E9925A152354C3DC00CA2082 /* aes256.c in Sources */,
 				106530E51D9B4021005B2C60 /* picotest.c in Sources */,
 				105900C71DCBECD800FB4085 /* aes.c in Sources */,
 				105900D11DCBED0600FB4085 /* cifra.c in Sources */,
+				E9925A162354C3DF00CA2082 /* chacha20.c in Sources */,
 				105900CE1DCBECF700FB4085 /* gf128.c in Sources */,
 				105900CC1DCBECF100FB4085 /* hmac.c in Sources */,
 				E9BC76D41EF3A37200EB7A09 /* chacha20.c in Sources */,