Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CERTIFICATE_VERIFY_FAILED: unable to get local issuer certificate using an letsencrypt-signed webserver #376

Closed
JustusFluegel opened this issue Feb 10, 2020 · 3 comments

Comments

@JustusFluegel
Copy link

JustusFluegel commented Feb 10, 2020

I get this error when I am trying to send an http.post() request to my express (nodejs) server using an letsencrypt certificate. It works fine if I directly open the url in chrome or firefox, both accept my certificate. I've tried it on an Android emulator too, but that doesn't work either.

Code:

final http.Response response = await http.post(
      UrlProvider.subPage(context, ["users", "login"]),
      headers: {"Content-Type": " application/json"},
      body: json.encode(
        {
          "username": usernameOrEmail.contains("@") ? null : usernameOrEmail,
          "email": usernameOrEmail.contains("@") ? usernameOrEmail : null,
          "password": password
        },
      ),
    );

The Url is https://subdomain.domain.de:3001/users/login , I've logged that and it works fine.

flutter doctor -v

[✓] Flutter (Channel beta, v1.14.6, on Linux, locale en_US.UTF-8)
    • Flutter version 1.14.6 at /usr/local/share/flutter
    • Framework revision fabeb2a16f (13 days ago), 2020-01-28 07:56:51 -0800
    • Engine revision c4229bfbba
    • Dart version 2.8.0 (build 2.8.0-dev.5.0 fc3af737c7)

 
[✓] Android toolchain - develop for Android devices (Android SDK version 29.0.3)
    • Android SDK at /home/myusername/Android/Sdk
    • Android NDK location not configured (optional; useful for native profiling support)
    • Platform android-29, build-tools 29.0.3
    • Java binary at: /usr/local/share/android-studio/jre/bin/java
    • Java version OpenJDK Runtime Environment (build 1.8.0_202-release-1483-b49-5587405)
    • All Android licenses accepted.

[✓] Chrome - develop for the web
    • Chrome at google-chrome

[✓] Android Studio (version 3.5)
    • Android Studio at /usr/local/share/android-studio
    • Flutter plugin version 43.0.1
    • Dart plugin version 191.8593
    • Java version OpenJDK Runtime Environment (build 1.8.0_202-release-1483-b49-5587405)

[✓] VS Code (version 1.41.1)
    • VS Code at /usr/share/code
    • Flutter extension version 3.8.1

[✓] Connected device (3 available)
    • Android SDK built for x86 • emulator-5554 • android-x86    • Android 10 (API 29) (emulator)
    • Chrome                    • chrome        • web-javascript • Google Chrome 78.0.3904.97
    • Web Server                • web-server    • web-javascript • Flutter Tools

• No issues found!

Call stack

E/flutter ( 9095): #20     PointerRouter.route 
package:flutter/…/gestures/pointer_router.dart:101
E/flutter ( 9095): #21     GestureBinding.handleEvent 
package:flutter/…/gestures/binding.dart:218
E/flutter ( 9095): #22     GestureBinding.dispatchEvent 
package:flutter/…/gestures/binding.dart:198
E/flutter ( 9095): #23     GestureBinding._handlePointerEvent 
package:flutter/…/gestures/binding.dart:156
E/flutter ( 9095): #24     GestureBinding._flushPointerEventQueue 
package:flutter/…/gestures/binding.dart:102
E/flutter ( 9095): #25     GestureBinding._handlePointerDataPacket 
package:flutter/…/gestures/binding.dart:86
E/flutter ( 9095): #26     _rootRunUnary  (dart:async/zone.dart:1138:13)
E/flutter ( 9095): #27     _CustomZone.runUnary  (dart:async/zone.dart:1031:19)
E/flutter ( 9095): #28     _CustomZone.runUnaryGuarded  (dart:async/zone.dart:933:7)
E/flutter ( 9095): #29     _invoke1  (dart:ui/hooks.dart:274:10)
E/flutter ( 9095): #30     _dispatchPointerDataPacket  (dart:ui/hooks.dart:183:5)
@wesQ3
Copy link

wesQ3 commented Feb 24, 2020

I don't think this is a dartlang issue. I recently ran into the same problem with a misconfigured webserver. Firefox and Chrome are not a good metric since they will check for missing intermediate certs in their trust stores (convenient, but non-standard).
You can check if your server is providing the necessary intermediate certificates with openssl s_client:

# CORRECT
$ openssl s_client -connect helloworld.letsencrypt.org:443
CONNECTED(00000005)
depth=2 O = Digital Signature Trust Co., CN = DST Root CA X3
verify return:1
depth=1 C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
verify return:1
depth=0 CN = helloworld.letsencrypt.org
verify return:1
---
Certificate chain
 0 s:CN = helloworld.letsencrypt.org
   i:C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
 1 s:C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
   i:O = Digital Signature Trust Co., CN = DST Root CA X3

My misconfigured server was not providing the intermediate certificates necessary to complete the cert chain back to a trusted root (and this worked without error in Firefox and Chrome!) :

# MISSING INTERMEDIATE CERT CHAIN
$ openssl s_client -connect demo.example.com:443                                                                                                          
CONNECTED(00000005)                                                                                                                                          
depth=0 CN = demo.example.com                                                                                                                              
verify error:num=20:unable to get local issuer certificate                                                                                                   
verify return:1                                                                                                                                              
depth=0 CN = demo.example.com                                                                                                                              
verify error:num=21:unable to verify the first certificate                                                                                                   
verify return:1                                                                                                                                              
---                                                                                                                                                          
Certificate chain                                                                                                                                            
 0 s:CN = demo.example.com                                                                                                                                 
   i:C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3

The solution is to provide the full certificate chain in your web server configuration. In our case, we had mistakenly used the host cert instead of the host-chain file provided by ACME.

@venkatesh-u
Copy link

I too ran into this issue, No need no change anything in code.
A Certificate chain have been configured at server end and it worked for me

@wamaeb
Copy link

wamaeb commented Oct 5, 2021

How do you configure nginx to use the full certificate chain?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants