2

I want to cross-sign a third-party root ca (third-party-ca) with my own root ca (r1). (Background: restricting usage)

To do this, I use

openssl x509-in third-party-ca.crt -CA /etc/pki/r1/ca.crt -CAkey /etc/pki/r1/private/ca.key -out third-party-ca-cross-signed.crt -set_serial 1000

This works, but keeps the Authority Key Identifier of the third-party-ca, which would need to be changed to the Subject Key Identifier of r1. (For a in-the-wild example, see letsencrypt ISRG X1 cross-signed by DST Root CA X3)

I'm able to add another Authority Key Identifier by creating an akiext and using -extfile akiext. However, this results in two Authority Key Identifier's.

How can I replace the existing Authority Key Identifier?

Zulakis
  • 4,153
  • 14
  • 48
  • 76

1 Answers1

1

In openssl x509 commandline, you can't selectively delete extension(s); you can use -clrext to drop all input extensions and configure in your -extfile the pre-existing extensions you do want (at minimum BC and KU) plus the new one(s). Note public subordinate or cross CA certs -- such as the one you link -- likely contain AIA and/or CRLDP as well as AKI, all of which are only correct for the issuer/parent you are replacing and thus should be replaced (or removed).

Alternatively you could write code; doing this using the API is straightforward. But that probably belongs on SO or maybe security.SX instead of here. (And you are expected to do part of the work.)

In your specific example, ISRG Root X1 is available both cross-signed by Identrust DST X3 and as a root -- if you start from the root cert it has no AKI or AIA/CRLDP that need to be removed.

Update: as revealed by a subsequent related question OpenSSL 3.0.0 up doesn't allow the non-root input case; it requires the old cert to be selfsigned (a root). Comments in the source indicate this was always intended, though not effectively enforced before.

dave_thompson_085
  • 3,262
  • 1
  • 16
  • 16
  • Shouldn't the CRLDP of the original certificate (that is getting cross-signed) be retained? – Zulakis Jun 15 '22 at 11:28
  • @Zulakis: no, because it points to where the _original_ CA publishes revocations of certs issued _by_ that CA. Your new/modified cert isn't issued by that CA and couldn't be revoked by that CA even if it knew about the new cert which it won't. If the new cert is to be revoked at all, it must be on a CRL (and/or OCSP) from _your new CA_. – dave_thompson_085 Jun 16 '22 at 03:36
  • So basically, if we want the original CRL to be in effect, the solution is to periodically fetch it, cross-sign it (can CRLs be cross-signed with openssl?) and publish it under our own URI? – Zulakis Jun 16 '22 at 10:49
  • @Zulakis: no, commandline can't do that, and you don't want to because the original CRL likely includes _other_ certs than the one you cross-signed, whose serials might collide with and wrongly revoke certs you cross-signed _from_ other issuers or even created outright. You should periodically check the status of the _specific cert(s)_ on the original CRL(s) and/or OCSP(s), and if one/any is revoked, _create your own_ CRL(s) and/or OCSP(s) including/adding _those specific cert(s)_ and distribute as needed for your reliers. ... – dave_thompson_085 Jun 18 '22 at 04:21
  • ... It used to be hard to get commandline to do CRL/OCSP for certs not issued by `openssl ca`, which yours are not and can't be, but since 1.0.2 in 2014 you can (though it looks oxymoronic) use `ca -valid` followed by `ca -revoke` to set up the 'database', and then `ca -gencrl` and/or `ocsp (responder)` to use it. – dave_thompson_085 Jun 18 '22 at 04:24