configure does not validate --with-ca-path and/or --with-ca-bundle #404

Closed
noloader opened this Issue Aug 31, 2015 · 19 comments

Projects

None yet

5 participants

@noloader

A configuration with the following:

./configure ... --with-ca-path=/usr/share/curl --with-ca-bundle=curl-ca-bundle.crt

Configures fine. At runtime, it produces an error:

curl: (77) error setting certificate verify locations:
  CAfile: curl-ca-bundle.crt
  CApath: /usr/share/curl

cURL has access to both the path and the file:

$ ls -Al /usr/share/curl
total 1496
-rw-r--r--@ 1 root  staff  258424 Aug 24 11:38 ca-bundle.crt
-rw-r--r--@ 1 root     wheel  258424 Aug 30 18:58 curl-ca-bundle.crt
-rw-r--r--  1 root     wheel  238102 Sep 24  2007 curl-ca-bundle.crt.bak

According to configure --help, I've set them as I'm supposed to. I provided the path via --with-ca-path, and I provided the filename via --with-ca-bundle

$ ./configure --help | grep "\-ca"
...
  --with-ca-bundle=FILE   File name to use as CA bundle
  --without-ca-bundle     Don't use a default CA bundle
  --with-ca-path=DIRECTORY
  --without-ca-path       Don't use a default CA path

There seems to be a lot of trouble with these options and lack of validation. Here's the number one search result: http://curl.haxx.se/mail/curlphp-2005-11/0038.html. In this report, the permissions were wrong. Configure could have easily tested it, but it did not.

Here's the number two search result: https://stackoverflow.com/questions/3160909/how-do-i-deal-with-certificates-using-curl-while-trying-to-access-an-https-url. The advice is to read the primary reference at http://curl.haxx.se/docs/sslcerts.html.

Unfortunately, the primary reference language is ambiguous and it lacks a working example. For example, when you say "FILE", do you mean just the filename (curl-ca-bundle.crt), or do you mean the fully qualified or absolute filename (/usr/share/curl/curl-ca-bundle.crt)?

It would be very helpful to users to state _exactly_ and _precisely_ what cURL expects or needs. It would also be very helpful to users if configure validated the --with-ca-path and --with-ca-bundle.

@noloader

And here's the result when using an absolute path for --with-ca-bundle, and _not_ using --with-ca-path:

$ ./src/.libs/curl https://www.google.com -o index.html
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current   Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
curl: (77) error setting certificate verify locations:
  CAfile: curl-ca-bundle.crt
  CApath: /usr/share/curl

And nothing set in the environment:

 $ printenv | grep -i curl
 PWD=/Users/<user>/curl-7.44.0

Using just --with-ca-path and _not_ using --with-ca-bundle produces the same result.

I have no idea why configure can't actually configure the library as specified, and where some of this stuff is coming from.

@bagder
Member
bagder commented Aug 31, 2015

It validates that the given file is a file. It validates that the given directory is a directory. Why are you passing configure a path you don't want it to use?

We could possibly add a check for a "-----BEGIN CERTIFICATE-----" line, but I really don't think this is a source for as much trouble as you're claiming. Most people don't build their own curl with configure and for those who do, the default path detection works for most of them.

Then you mix in another matter, namely the sslcerts document. It speaks of file as in you specify the file name. That can be relative or absolute, just like how you specify file name to any application in your system.

@bagder bagder added the SSL/TLS label Aug 31, 2015
@wmark
wmark commented Sep 3, 2015

From the point of release engineering I'd say, accept what is provided to configure and don't validate the paths or files then and there. I could be compiling curl on a machine completely different from the target environment.

@bagder
Member
bagder commented Sep 3, 2015

Good point. I see no reason to change our current behavior.

@bagder bagder closed this Sep 3, 2015
@noloader
noloader commented Sep 4, 2015

It sounds like you guys are effectively saying, cURL had been downloaded hundreds of thousands or millions of time; and most of those times its so someone can build on one machine and install on another machine. I'd say that's pretty tenuous.

Based on decades of problems with it, I'd say maybe its time to rethink it. Or at least clean up the documentation so its clear and concise.

@bagder
Member
bagder commented Sep 4, 2015

@noloader, what is the problem with giving configure the correct path? Why is this such a problem? And no, even if the majority doesn't build on one machine to pass it on to another, it is a use case that we support and that is not unreasonable so why not support it?

The vast majority of users who run configure will of course not even use those options as it is fairly good at detecting the system's default paths by itself.

Based on decades of problems with it,

You spent a decade trying to give it the correct CA path?

@noloader
noloader commented Sep 4, 2015

@badger - "what is the problem with giving configure the correct path..." - nothing. I gave it an existing path and an existing file name. It resulted in a runtime error.

@bagder
Member
bagder commented Sep 4, 2015

so how is that configure's fault?

@noloader
noloader commented Sep 4, 2015

@badger - its a problem with the library. Since its a configuration option, I'm guessing its something configure can detect.

@jay
Member
jay commented Sep 5, 2015

It looks like @noloader thought he could pass the certificate bundle's filename in --with-ca-bundle and the path to that certificate bundle in --with-ca-path.

curl: (77) error setting certificate verify locations:
CAfile: curl-ca-bundle.crt
CApath: /usr/share/curl

  --with-ca-bundle=FILE   File name to use as CA bundle
  --without-ca-bundle     Don't use a default CA bundle
  --with-ca-path=DIRECTORY
                          Directory to use as CA path
  --without-ca-path       Don't use a default CA path

But OpenSSL expects the full path to the certificate bundle in CAfile and uses CApath to look up CA certificates stored individually, each in a filename that is the hash of the subject name [1].

If someone is unfamiliar with OpenSSL that is a mistake they could make. So I think he has a point. What if we change it to something like this:

  --with-ca-bundle=FILE   Path to a filename that is a certificate bundle.
                          Example: /etc/ca-bundle.crt
  --without-ca-bundle     Don't use a default CA bundle
  --with-ca-path=DIRECTORY
                          Path to a directory containing CA certificates stored
                          individually. Refer to OpenSSL for the format.
                          Example: /etc/ca-certificates
  --without-ca-path       Don't use a default CA path

I don't have much of an opinion on more safety checks except I don't think they should cause an error. At the most I'd +1 a warning after configure completes like "WARNING: The certificate bundle was not found at the specified location."

@jay jay reopened this Sep 5, 2015
@bagder
Member
bagder commented Sep 5, 2015

I don't have much of an opinion on more safety checks except I don't think they should cause an error. At the most I'd +1 a warning

We could do a warning (and yeah we cannot do an error due to said cross-compiling or "build-here and run-there" setups). Assuming the check works properly independently of TLS backend in use.

The problem with configure warnings is probably that they scroll down fast and are easy to miss.

@noloader
noloader commented Sep 6, 2015

One quick comment...

If someone is unfamiliar with OpenSSL that is a mistake they could make....

I'm familiar with OpenSSL. But configure and http://curl.haxx.se/docs/sslcerts.html. don't state cURL wants the c_hash gear. When I RTFM, I try to perform literal reads, and I try to avoid guesses or leaps.

If PATH is a path to the c_hash gear, then state it. And you should also state you want an absolute path for FILE (--with-ca-bundle=FILE), and not a relative one.

@jay
Member
jay commented Sep 6, 2015

alright here's draft 1

  --with-ca-bundle=FILE   Path to a file containing CA certificates (example:
                          /etc/ca-bundle.crt)
  --without-ca-bundle     Don't use a default CA bundle
  --with-ca-path=DIRECTORY
                          Path to a directory containing CA certificates
                          stored individually, with their filenames in a hash
                          format. This option can be used with OpenSSL, GnuTLS
                          and PolarSSL backends. Refer to OpenSSL c_rehash for
                          details. (example: /etc/certificates)
  --without-ca-path       Don't use a default CA path

if the path is not found you should see this when configure completes:

  ca cert bundle:   foo    warning: path not found
  ca cert path:     bar    warning: path not found

I'll have to add parentheses around the warning

Anyone familiar with autoconf want to give it a look? I rarely do it so I'm not sure if all the syntax and logic is ok.
https://github.com/bagder/curl/compare/master...jay:warn_invalid_cafile?expand=1

as far as the sslcerts page goes I don't know what to put there if anything. yes it doesn't discuss the configure options, but should it.

also i said 'full path' in my last post i don't know why i wrote that. it takes a path, not necessarily a full path.

@bagder
Member
bagder commented Sep 6, 2015

And you should also state you want an absolute path for FILE (--with-ca-bundle=FILE), and not a relative one.

I don't think there's a strict requirement to have an absolute path there, although of course it seems nuts to not use one for most users.

@bagder
Member
bagder commented Sep 6, 2015

Anyone familiar with autoconf want to give it a look?

Looks good to me!

@jay jay self-assigned this Nov 6, 2015
@bagder
Member
bagder commented Dec 24, 2015

@jay, you intend to merge that or are there any second thoughts?

@jay
Member
jay commented Dec 26, 2015

I'm pretty sure I intended to test it more but I forgot. I'll take a look soon.

@jay jay added a commit that referenced this issue Feb 25, 2016
@jay jay configure: warn on invalid ca bundle or path
- Warn if --with-ca-bundle file does not exist.

- Warn if --with-ca-path directory does not contain certificates.

- Improve help messages for both.

Example configure output:

  ca cert bundle:   /some/file   (warning: certs not found)
  ca cert path:     /some/dir   (warning: certs not found)

Bug: #404
Reported-by: Jeffrey Walton
3ae77f0
@jay
Member
jay commented Feb 25, 2016

@noloader Thank you for your suggestion. I have updated the help text and also added a warning. The changes landed in 3ae77f0.

Help looks like this:

  --with-ca-bundle=FILE   Path to a file containing CA certificates (example:
                          /etc/ca-bundle.crt)
  --without-ca-bundle     Don't use a default CA bundle
  --with-ca-path=DIRECTORY
                          Path to a directory containing CA certificates
                          stored individually, with their filenames in a hash
                          format. This option can be used with OpenSSL, GnuTLS
                          and PolarSSL backends. Refer to OpenSSL c_rehash for
                          details. (example: /etc/certificates)
  --without-ca-path       Don't use a default CA path

Warning looks like this:

  ca cert bundle:   /some/file   (warning: certs not found)
  ca cert path:     /some/dir   (warning: certs not found)
@jay jay closed this Feb 25, 2016
@JCMais
JCMais commented Jul 12, 2016

looks like someone needs to have their account suspended from GitHub.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment