Skip to content

Intermediate certs don't work with SNICallback #2772

Description

@fastner

If I give key, cert and ca via options field to https.createServer the whole key chain is returned on connection (correct behaviour). If I try to do the same via SNICallback it is not possible to set whole key chain.

Example code:

var https = require("https");
var fs = require("fs");
var tls = require("tls");

var o = {
    key: fs.readFileSync("example.com.key"),
    cert: fs.readFileSync("example.com.crt"),
    ca: fs.readFileSync("intermediate.crt")
};

var context = tls.createSecureContext(o);
var options = {
    SNICallback: function(servername, cb) {
        return cb(null, context);
    },

    ca: o.ca
};

https.createServer(options, function(req, res) {
    res.writeHead(200);
    res.end("hello world\n");
}).listen(8000);

Now try to connect via openssl:

openssl s_client -servername example.com -connect localhost:8000

Expected and real behaviour is Verify return code: 0 (OK).

If I remove the ca in options map like this

var options = {
    SNICallback: function(servername, cb) {
        return cb(null, context);
    }
};

and rerun openssl client the return code is Verify return code: 21 (unable to verify the first certificate)which indicates that not the whole key chain is returned.
The expected behaviour is Verify return code: 0 (OK) as the ca field is given to tls.createSecureContext.

This occures in io.js 3.x and Node.js 4.0.0.

Activity

  1. added
    tlsIssues and PRs related to the tls subsystem.
    on Sep 9, 2015
  2. gregholland commented on Oct 24, 2015

    @gregholland

    +1 - I've just hit the same issue.

  3. bnoordhuis commented on Oct 25, 2015

    @bnoordhuis
    Member

    /cc @nodejs/crypto

  4. alexlamsl commented on Oct 25, 2015

    @alexlamsl

    Would concatenating those intermediate certificates alongside your cert instead of ca works in this case?

  5. indutny commented on Oct 25, 2015

    @indutny
    Member

    It should work. Working on fix.

  6. fastner commented on Oct 25, 2015

    @fastner
    Author

    @alexlamsl did you mean something like

    var o = {
      key: fs.readFileSync("example.com.key"),
      ca: fs.readFileSync("example.com.crt") + "\n" + fs.readFileSync("intermediate.crt")
    };
    
  7. alexlamsl commented on Oct 25, 2015

    @alexlamsl

    @fastner I just did it on the crt file itself:

    -----BEGIN CERTIFICATE----- 
     (Your Primary SSL certificate: example.com.crt) 
    -----END CERTIFICATE-----  
    -----BEGIN CERTIFICATE----- 
     (Your Intermediate certificate: intermediate.crt) 
    -----END CERTIFICATE----- 
    

    And then specify only cert and no ca in the options.

  8. gregholland commented on Oct 27, 2015

    @gregholland

    @alexlamsl Your solution to concatenate cert and intermediates works well - thanks for the solution.

  9. added a commit that references this issue on Nov 17, 2015
    05f0549
  10. added a commit that references this issue on Jan 28, 2016
    dac9e38
  11. added 3 commits that reference this issue on Feb 11, 2016
    c841d57
    5cf132a
    aefb20a
  12. anatolsommer commented on Mar 13, 2016

    @anatolsommer

    Maybe it's a dumb question or the wrong place to ask, but is the cert: cert+'\n'+ca workaround safe to use or do I have to be afraid that this causes trouble with future node versions?

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    tlsIssues and PRs related to the tls subsystem.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions