Merge pull request #345 from h2o/kazuho/server-cipher-preference

knob to select cipher-suite based on server's preference
diff --git a/appveyor.yml b/appveyor.yml
new file mode 100644
index 0000000..53454bd
--- /dev/null
+++ b/appveyor.yml
@@ -0,0 +1,25 @@
+version: build{build}
+image: Visual Studio 2017
+
+environment:
+  matrix:
+    - platform: x86
+      configuration: Debug
+      OPENSSLDIR: C:\OpenSSL-v11-Win32
+    - platform: x64
+      configuration: Debug
+      OPENSSL64DIR: C:\OpenSSL-v11-Win64
+    - platform: x86
+      configuration: Release
+      OPENSSLDIR: C:\OpenSSL-v11-Win32
+    - platform: x64
+      configuration: Release
+      OPENSSL64DIR: C:\OpenSSL-v11-Win64
+
+install:
+  - ps: git submodule --quiet update --init --recursive
+
+build:
+  parallel: true
+  project: picotlsvs\picotlsvs.sln
+
diff --git a/lib/openssl.c b/lib/openssl.c
index 80613bb..c9806ad 100644
--- a/lib/openssl.c
+++ b/lib/openssl.c
@@ -49,7 +49,6 @@
 #define _CRT_SECURE_NO_WARNINGS
 #endif
 #pragma warning(disable : 4996)
-#include <ms/applink.c>
 #endif
 
 #if !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L
@@ -1231,7 +1230,27 @@
         ret = PTLS_ERROR_LIBRARY;
         goto Exit;
     }
-    X509_STORE_CTX_set_purpose(verify_ctx, is_server ? X509_PURPOSE_SSL_SERVER : X509_PURPOSE_SSL_CLIENT);
+
+    {
+        X509_VERIFY_PARAM *params;
+        if ((params = X509_VERIFY_PARAM_new()) == NULL) {
+            ret = PTLS_ERROR_NO_MEMORY;
+            goto Exit;
+        }
+        X509_VERIFY_PARAM_set_purpose(params, is_server ? X509_PURPOSE_SSL_SERVER : X509_PURPOSE_SSL_CLIENT);
+        X509_VERIFY_PARAM_set_depth(params, 98); /* use the default of OpenSSL 1.0.2 and above; see `man SSL_CTX_set_verify` */
+        if (server_name != NULL) {
+            if (ptls_server_name_is_ipaddr(server_name)) {
+                X509_VERIFY_PARAM_set1_ip_asc(params, server_name);
+            }
+            else {
+                X509_VERIFY_PARAM_set1_host(params, server_name, 0);
+                X509_VERIFY_PARAM_set_hostflags(params, X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS);
+            }
+        }
+        X509_STORE_CTX_set0_param(verify_ctx, params); /* params will be freed alongside verify_ctx */
+    }
+
     if (X509_verify_cert(verify_ctx) != 1) {
         int x509_err = X509_STORE_CTX_get_error(verify_ctx);
         switch (x509_err) {
@@ -1251,6 +1270,7 @@
         case X509_V_ERR_CERT_REJECTED:
             ret = PTLS_ALERT_UNKNOWN_CA;
             break;
+        case X509_V_ERR_HOSTNAME_MISMATCH:
         case X509_V_ERR_INVALID_CA:
             ret = PTLS_ALERT_BAD_CERTIFICATE;
             break;
@@ -1261,27 +1281,6 @@
         goto Exit;
     }
 
-#ifdef X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS
-    /* verify CN */
-    if (server_name != NULL) {
-        if (ptls_server_name_is_ipaddr(server_name)) {
-            ret = X509_check_ip_asc(cert, server_name, 0);
-        } else {
-            ret = X509_check_host(cert, server_name, strlen(server_name), X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS, NULL);
-        }
-        if (ret != 1) {
-            if (ret == 0) { /* failed match */
-                ret = PTLS_ALERT_BAD_CERTIFICATE;
-            } else {
-                ret = PTLS_ERROR_LIBRARY;
-            }
-            goto Exit;
-        }
-    }
-#else
-#warning "hostname validation is disabled; OpenSSL >= 1.0.2 or LibreSSL >= 2.5.0 is required"
-#endif
-
     ret = 0;
 
 Exit:
@@ -1383,7 +1382,7 @@
 {
     ptls_openssl_raw_pubkey_verify_certificate_t *self = (ptls_openssl_raw_pubkey_verify_certificate_t *)_self;
     int ret = PTLS_ALERT_BAD_CERTIFICATE;
-    ptls_iovec_t expected_pubkey = {};
+    ptls_iovec_t expected_pubkey = { 0 };
 
     assert(num_certs != 0);
 
diff --git a/lib/ptlsbcrypt.c b/lib/ptlsbcrypt.c
index 43c442f..8f4561f 100644
--- a/lib/ptlsbcrypt.c
+++ b/lib/ptlsbcrypt.c
@@ -135,7 +135,7 @@
     ULONG cbResult;
     NTSTATUS ret;
     uint8_t eiv[PTLS_MAX_IV_SIZE];
-    int i;
+    size_t i;
     uint64_t seq = 0;
     size_t processed = 0;
     uint8_t const *v_in = input;
diff --git a/misc/build_picotls.ps1 b/misc/build_picotls.ps1
new file mode 100644
index 0000000..ab1e96c
--- /dev/null
+++ b/misc/build_picotls.ps1
@@ -0,0 +1,11 @@
+# Match expectations of picotlsvs project.
+mkdir $dir\include\
+foreach ($dir in "$Env:OPENSSLDIR","$Env:OPENSSL64DIR") {
+    if ($dir) {
+        cp "$dir\lib\libcrypto.lib" "$dir"
+        cp C:\OpenSSL-Win32\include\openssl\applink.c "$dir\include\openssl"
+        echo "Copied applink.c to $dir\include\openssl"
+    }
+}
+
+# msbuild "/p:Configuration=$Env:Configuration" "/p:Platform=$Env:Platform" /m picotlsvs\picotlsvs.sln
diff --git a/picotlsvs/picotlsvs.sln b/picotlsvs/picotlsvs.sln
index 6be9680..e6140c4 100644
--- a/picotlsvs/picotlsvs.sln
+++ b/picotlsvs/picotlsvs.sln
@@ -16,6 +16,7 @@
 		{559AC085-1BEF-450A-A62D-0D370561D596} = {559AC085-1BEF-450A-A62D-0D370561D596}
 		{499B82B3-F5A5-4C2E-91EF-A2F77CBC33F5} = {499B82B3-F5A5-4C2E-91EF-A2F77CBC33F5}
 		{56C264BF-822B-4F29-B512-5B26157CA2EC} = {56C264BF-822B-4F29-B512-5B26157CA2EC}
+		{55F22DE6-EAAE-4279-97B7-84FAAB7F29BB} = {55F22DE6-EAAE-4279-97B7-84FAAB7F29BB}
 		{497433FE-B252-4985-A504-54EB791F57F4} = {497433FE-B252-4985-A504-54EB791F57F4}
 	EndProjectSection
 EndProject
diff --git a/picotlsvs/picotlsvs/picotlsvs.vcxproj b/picotlsvs/picotlsvs/picotlsvs.vcxproj
index 35810aa..98abdd7 100644
--- a/picotlsvs/picotlsvs/picotlsvs.vcxproj
+++ b/picotlsvs/picotlsvs/picotlsvs.vcxproj
@@ -92,7 +92,7 @@
     </ClCompile>
     <Link>
       <SubSystem>Console</SubSystem>
-      <AdditionalLibraryDirectories>$(OPENSSLDIR);$(OutDir)</AdditionalLibraryDirectories>
+      <AdditionalLibraryDirectories>$(OPENSSLDIR);$(OPENSSLDIR)\lib;$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <AdditionalDependencies>picotls-core.lib;picotls-openssl.lib;picotls-minicrypto.lib;picotls-minicrypto-deps.lib;libcrypto.lib;bcrypt.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
     </Link>
   </ItemDefinitionGroup>
@@ -124,7 +124,7 @@
       <SubSystem>Console</SubSystem>
       <EnableCOMDATFolding>true</EnableCOMDATFolding>
       <OptimizeReferences>true</OptimizeReferences>
-      <AdditionalLibraryDirectories>$(OPENSSLDIR);$(OutDir)</AdditionalLibraryDirectories>
+      <AdditionalLibraryDirectories>$(OPENSSLDIR);$(OPENSSLDIR)\lib;$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <AdditionalDependencies>picotls-core.lib;picotls-openssl.lib;picotls-minicrypto.lib;picotls-minicrypto-deps.lib;libcrypto.lib;bcrypt.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
     </Link>
   </ItemDefinitionGroup>
diff --git a/picotlsvs/ptlsbench/ptlsbench.vcxproj b/picotlsvs/ptlsbench/ptlsbench.vcxproj
index 22e5c16..45d3efe 100644
--- a/picotlsvs/ptlsbench/ptlsbench.vcxproj
+++ b/picotlsvs/ptlsbench/ptlsbench.vcxproj
@@ -117,7 +117,7 @@
     <Link>
       <SubSystem>Console</SubSystem>
       <GenerateDebugInformation>true</GenerateDebugInformation>
-      <AdditionalLibraryDirectories>$(OPENSSLDIR);$(OutDir)</AdditionalLibraryDirectories>
+      <AdditionalLibraryDirectories>$(OPENSSLDIR);$(OPENSSLDIR)\lib;$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <AdditionalDependencies>bcrypt.lib;picotls-core.lib;picotls-openssl.lib;picotls-bcrypt.lib;picotls-minicrypto.lib;picotls-minicrypto-deps.lib;libcrypto.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
     </Link>
   </ItemDefinitionGroup>
@@ -139,7 +139,7 @@
       <EnableCOMDATFolding>true</EnableCOMDATFolding>
       <OptimizeReferences>true</OptimizeReferences>
       <GenerateDebugInformation>true</GenerateDebugInformation>
-      <AdditionalLibraryDirectories>$(OPENSSLDIR);$(OutDir)</AdditionalLibraryDirectories>
+      <AdditionalLibraryDirectories>$(OPENSSLDIR);$(OPENSSLDIR)\lib;$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <AdditionalDependencies>picotls-core.lib;picotls-openssl.lib;picotls-minicrypto.lib;picotls-minicrypto-deps.lib;libcrypto.lib;bcrypt.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
     </Link>
   </ItemDefinitionGroup>
diff --git a/picotlsvs/testopenssl/testopenssl.vcxproj b/picotlsvs/testopenssl/testopenssl.vcxproj
index 6c7b156..3787eb8 100644
--- a/picotlsvs/testopenssl/testopenssl.vcxproj
+++ b/picotlsvs/testopenssl/testopenssl.vcxproj
@@ -93,7 +93,7 @@
     </ClCompile>
     <Link>
       <SubSystem>Console</SubSystem>
-      <AdditionalLibraryDirectories>$(OPENSSLDIR);$(OutDir)</AdditionalLibraryDirectories>
+      <AdditionalLibraryDirectories>$(OPENSSLDIR);$(OPENSSLDIR)\lib;$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <AdditionalDependencies>picotls-core.lib;picotls-openssl.lib;picotls-minicrypto.lib;picotls-minicrypto-deps.lib;libcrypto.lib;bcrypt.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
     </Link>
   </ItemDefinitionGroup>
@@ -127,7 +127,7 @@
       <SubSystem>Console</SubSystem>
       <EnableCOMDATFolding>true</EnableCOMDATFolding>
       <OptimizeReferences>true</OptimizeReferences>
-      <AdditionalLibraryDirectories>$(OPENSSLDIR);$(OutDir)</AdditionalLibraryDirectories>
+      <AdditionalLibraryDirectories>$(OPENSSLDIR);$(OPENSSLDIR)\lib;$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <AdditionalDependencies>picotls-core.lib;picotls-openssl.lib;picotls-minicrypto.lib;picotls-minicrypto-deps.lib;libcrypto.lib;bcrypt.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
     </Link>
   </ItemDefinitionGroup>