Repository: thecoshman/http (language: rust)

Issue:
`--gen-ssl` do not work on MacOS
Mac OS 10.15 Beta 
http 1.5.0

```bash
$ http --gen-ssl
Opening TLS certificate failed.
```
Does it require some perquisites to do generating and signing? 


Discussion / hints:
Well, yes, it does require `openssl`, but if you got to opening the cert, then that's not it.

Can you try running `http --gen-ssl --temp-dir .` and check back with the contents of `./{slug}/tls/`?
It's created `tls.crt`, `tls.key` and `tls.p12` non-empty files. Attempt to pass `.p12` or `.key` to `--ssl` display the same 'Opening TLS certificate failed'. Passing `.crt` panics with 
```
thread 'main' panicked at 'called `Option::unwrap()` on a `None` value', src/libcore/option.rs:347:21
stack backtrace:
   0: std::sys::unix::backtrace::tracing::imp::unwind_backtrace
   1: std::sys_common::backtrace::_print
   2: std::panicking::default_hook::{{closure}}
   3: std::panicking::default_hook
   4: std::panicking::rust_panic_with_hook
   5: std::panicking::continue_panic_fmt
   6: rust_begin_unwind
   7: core::panicking::panic_fmt
   8: core::panicking::panic
   9: native_tls::imp::Pkcs12::from_der
  10: native_tls::Pkcs12::from_der
  11: hyper_native_tls::NativeTlsServer::new
  12: http::ops::try_ports
  13: http::actual_main
  14: http::main
  15: std::rt::lang_start::{{closure}}
  16: std::panicking::try::do_call
  17: __rust_maybe_catch_panic
  18: std::rt::lang_start_internal
  19: main
```
which probably make sense because I pass wrong file (not really familiar with ssl keys). 
Hmm... Theoretically, passing the `.p12` file to `--ssl` should work.

Could you (a) try running `http --ssl tls/tls.p12` on this attachment: [tls.zip](https://github.com/thecoshman/http/files/3396686/tls.zip).

And could you post the key pack your `http` generates? I'm starting to think your `openssl` version/build generates incompatible keys
Attempt to open tls key from your pack ends with the same `Opening TLS certificate failed.`. 
Generated keys:  [tls.zip](https://github.com/thecoshman/http/files/3397346/tls.zip)

i think there's a chance it's an issue with new MacOS Beta update. It did some nasty stuff about access  permissions to files (similar to [docker](https://github.com/docker/for-mac/issues/3698), I have this issue too). 



Your certificate opens just fine on my machine so :v

Did you try running `http --gen-ssl` as root? If that works, that'd definitely confirm that this is the same issue as that docker one, which I can't really do anything about, sadly
Running as root display same error. I will try `first aid` option later and let you know if it will fix anything. 
So, I tried first aid and it fixed docker but not httplz. Still fails the same way. Is there any suggestion how can i check why exactly it fails? It's emmitted [here](https://github.com/thecoshman/http/blob/ab89d02aadaf530593719c4bf2c86ae9ac71bbb9/src/ops.rs#L1090) I tnink, but don't know how to check what exactly went wrong. 
Probably it is an issue with outdated `hyper` v10.x crate, which `iron` based upon. It's removed some [API](https://github.com/hyperium/hyper/issues/1218) (v11.x) and suggest to use `hyper-tls` and a `hyper-tls-native` some backport compatibility thing for current hyper 10.x. Could it be the case? 
You could replace this line

```rust
try!(NativeTlsServer::new(id, pw).map_err(|_| {
```

with

```rust
try!(NativeTlsServer::new(id, pw).map_err(|e| { eprintln!("{}", e);
```

to see the specific error.

As for openssl: yeah, it's a Problem and I wouldn't be surprised, but I couldn't find any way to override the `hyper` &a. versions (see #85).
For now, the whole stack is pinned down by `iron`, at least until [my fix PR](https://github.com/iron/iron/pull/612) is merged, sadly
`eprintl` yielded 
```
error initializing acceptor: MAC verification failed during PKCS12 import (wrong password?)
Opening TLS certificate failed.
```
And it's also probably some [issue](https://discussions.apple.com/thread/3630009) with macOS distribution. Is there a way to generate and use some password/passphrase for generated key? If not, I think we can close this question as dupe of #85.
There's not, short of generating the key manually.

Alright, then, closing in favour of #85.
Update: the PR has been merged, if you reinstall `http`, the issue should be resolved by default!
Tested on 8189d6a. Same error with PKCS12 import. 
Well fuck

Fix patch:
diff --git a/Cargo.toml b/Cargo.toml
index 1048410..dde23da 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -9,7 +9,7 @@ categories = ["network-programming", "web-programming::http-server"]
 license = "MIT"
 build = "build.rs"
 # Remember to also update in appveyor.yml
-version = "1.11.1"
+version = "1.11.2"
 # Remember to also update in http.md
 authors = ["thecoshman <rust@thecoshman.com>",
            "nabijaczleweli <nabijaczleweli@nabijaczleweli.xyz>",
diff --git a/appveyor.yml b/appveyor.yml
index 86b9ada..0904d17 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -1,4 +1,4 @@
-version: 1.11.1-{build}
+version: 1.11.2-{build}
 
 skip_tags: false
 
@@ -18,6 +18,7 @@ install:
   - pacman --noconfirm -U C:\pacman.txz
   - bash -lc "pacman --needed --noconfirm -Sy pacman-mirrors"
   - bash -lc "pacman --noconfirm -Sy pacman"
+  - bash -lc "pacman --noconfirm -Sy"
   - bash -lc "pacman --noconfirm -Su"
   - bash -lc "pacman --noconfirm -Sy"
   - bash -lc "pacman --noconfirm -S mingw-w64-x86_64-toolchain mingw-w64-x86_64-nsis unzip"
@@ -32,21 +33,21 @@ build: off
 build_script:
   - git submodule update --init --recursive
   - cargo build --verbose --release
-  - cp target\release\http.exe http-v1.11.1.exe
-  - strip --strip-all --remove-section=.comment --remove-section=.note http-v1.11.1.exe
-  - makensis -DHTTP_VERSION=v1.11.1 install.nsi
+  - cp target\release\http.exe http-v1.11.2.exe
+  - strip --strip-all --remove-section=.comment --remove-section=.note http-v1.11.2.exe
+  - makensis -DHTTP_VERSION=v1.11.2 install.nsi
 
 test: off
 test_script:
   - cargo test --verbose --release
 
 artifacts:
-  - path: http-v1.11.1.exe
-  - path: http v1.11.1 installer.exe
+  - path: http-v1.11.2.exe
+  - path: http v1.11.2 installer.exe
 
 deploy:
   provider: GitHub
-  artifact: /http.*v1.11.1.*\.exe/
+  artifact: /http.*v1.11.2.*\.exe/
   auth_token:
     secure: ZTXvCrv9y01s7Hd60w8W7NaouPnPoaw9YJt9WhWQ2Pep8HLvCikt9Exjkz8SGP9P
   on:
diff --git a/http.md b/http.md
index 62c4d52..4ddd306 100644
--- a/http.md
+++ b/http.md
@@ -57,9 +57,13 @@ pass parameters like what port to use.
 
   --gen-ssl
 
-    Generate a passwordless, single-use TLS self-signed certificate
+    Generate a single-use self-signed TLS certificate
     and use it for this session.
 
+    The password for the certificate is the empty string,
+    except on MacOS, where it's "password", since the platform libssl
+    refuses to import passwordless certificates.
+
     Exclusive with --ssl. Default: false.
 
   --auth [USERNAME[:PASSWORD]]
diff --git a/src/main.rs b/src/main.rs
index 124533c..9ebcbce 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -81,7 +81,7 @@ fn result_main() -> Result<(), Error> {
         after: opts.request_bandwidth.map(ops::LimitBandwidthMiddleware::new),
     };
     let mut responder = if let Some(p) = opts.port {
-        if let Some(&((ref id, _), ref pw)) = opts.tls_data.as_ref() {
+        if let Some(&((_, ref id), ref pw)) = opts.tls_data.as_ref() {
                 Iron::new(handler).https((opts.bind_address, p),
                                          NativeTlsServer::new(id, pw).map_err(|err| {
                         Error {
diff --git a/src/ops/mod.rs b/src/ops/mod.rs
index 8bccef9..a60f96b 100644
--- a/src/ops/mod.rs
+++ b/src/ops/mod.rs
@@ -1513,20 +1513,40 @@ pub fn generate_tls_data(temp_dir: &(String, PathBuf)) -> Result<((String, PathB
         return Err(exit_err(true, &mut child, &es));
     }
 
-    let mut child =
-        Command::new("openssl").args(&["pkcs12", "-export", "-out", "tls.p12", "-inkey", "tls.key", "-in", "tls.crt", "-passin", "pass:", "-passout", "pass:"])
-            .current_dir(&tls_dir)
-            .stdin(Stdio::null())
-            .stdout(Stdio::null())
-            .stderr(Stdio::null())
-            .spawn()
-            .map_err(|error| err(false, "spawn", error.to_string()))?;
+    let mut child = Command::new("openssl").args(&["pkcs12",
+                "-export",
+                "-out",
+                "tls.p12",
+                "-inkey",
+                "tls.key",
+                "-in",
+                "tls.crt",
+                "-passin",
+                "pass:",
+                "-passout",
+                if cfg!(target_os = "macos") {
+                    "pass:password"
+                } else {
+                    "pass:"
+                }])
+        .current_dir(&tls_dir)
+        .stdin(Stdio::null())
+        .stdout(Stdio::null())
+        .stderr(Stdio::null())
+        .spawn()
+        .map_err(|error| err(false, "spawn", error.to_string()))?;
     let es = child.wait().map_err(|error| err(false, "wait", error.to_string()))?;
     if !es.success() {
         return Err(exit_err(false, &mut child, &es));
     }
 
-    Ok(((format!("{}/tls/tls.p12", temp_dir.0), tls_dir.join("tls.p12")), String::new()))
+    Ok(((format!("{}/tls/tls.p12", temp_dir.0), tls_dir.join("tls.p12")),
+        if cfg!(target_os = "macos") {
+                "password"
+            } else {
+                ""
+            }
+            .to_string()))
 }
 
 /// Generate random username:password auth credentials.


Test patch: