5

I have a self-signed CA that I want to rotate the key for. I want to use cross-signing to facilitate this, with gradual replacement of the certificate on the clients so they can still communicate.

I'm using cfssl, but can't figure out practically how to get this to work. For testing purposes I've generated two new CAs with identical CNs and cross-signed them:

cfssl gencert -initca ca-csr-A.json | cfssljson -bare ca-A
cfssl gencert -initca ca-csr-B.json | cfssljson -bare ca-B

cfssl sign -ca ca-A.pem -ca-key ca-A-key.pem -config ca-config.json ca-B.csr | cfssljson -bare ca-B-by-A
cfssl sign -ca ca-B.pem -ca-key ca-B-key.pem -config ca-config.json ca-A.csr | cfssljson -bare ca-A-by-B

I've then created a new client certificate, signed with A's private key and the A certificate cross-signed by B:

cfssl gencert -ca=ca-A-by-B.pem -ca-key=ca-A-key.pem -config=ca-config.json child-csr.json | cfssljson -bare child

I've then tried to verify (using openssl verify) the new client certificate with either original A, original B or either of the cross-signed CAs, but can't work out the incantation. I've tried bundling ca-A-by-B.pem and ca-B.pem, and tried bundling the client with ca-A-by-B.pem as an intermediary, but they don't work either.

I think I missing something obvious, or just misunderstanding cross-signing completely. Is this even possible?

2
  • Can you show the openssl verify command? I suspect that's where your problem is. Commented Dec 9, 2018 at 1:18
  • It seems odd that your end-entity is issued by ca-A-by-B, shouldn't it be issued by the ca-A self-signed root cert? Commented Dec 9, 2018 at 1:28

1 Answer 1

1

These answers might be helpful:


Alright, so the idea would be to place the cross-certs into the trust stores of your clients so that during cert validation they can path-build from the CA they don't trust to the one they do.

Your test-scenario is that you have an end-entity cert issued by ca-A, and a client verifier who only trusts ca-B. You also have a ca-A-by-B cross-cert that you can give to the client so that it can path-build between the two CAs. I believe the correct openssl command-line incantation to simulate that would be:

  • -CAfile ca-B.pem so that ca-B is "in the trust store".
  • -untrusted ca-A-by-B.pem so that the verifier is aware that it can use that cert for path-building, but doesn't consider it a trusted root.
  • < (cat ca-A.pem child.pem) simulate receiving a cert-bundle containing the end-entity cert and its issuer (ca-A).

all together:

openssl verify -verbose -CAfile ca-B.pem -untrusted ca-A-by-B.pem < (cat ca-A.pem child.pem)

I haven't actually tried this cause I'm too lazy to generate test certs, but let me know if it helps (or if I need to make corrections).

2
  • That works, but I do still get: error 18 at 0 depth lookup:self signed certificate OK Which I assume is it trying to validate the first cert in the bundle. Thanks for your help!
    – boffbowsh
    Commented Dec 10, 2018 at 7:24
  • Hmm, looks like OpenSSL is picky that the CN of each cert in the chain be different? I wonder if openssl just doesn't support link certs (a cross-cert from a CA to itself on a new key). See: stackoverflow.com/questions/19726138/… Commented Dec 10, 2018 at 14:56

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .