7

I'm building a CA based on the OpenSSL command line tools. I don't want to use the openssl ca tool and its file based database though, instead I create certificates using the openssl x509 tool directly and assign a random serial. (I want to manage revocations, serials and policies myself.)

This all works, the problem is that the subject line is copied directly from the CSR into the certificate when issuing a new certificate. I want to be able to override the subject. Unfortunately the x509 command does not provide a -subj <arg> parameter like the ca command does.

As a workaround, I tried to rewrite the CSR itself. I can easily change the subject using openssl req -in oldcsr.pem -subj "newsubj" -out newcsr.pem. But then of course the CSR signature is not valid anymore and openssl x509 complains that the "signature did not match the certificate request". And I didn't find an easy way to ignore the signature.

Is there a way to override the subject of a CSR when generating a certificate, without using the openssl ca tool?

Danilo Bargen
  • 336
  • 1
  • 4
  • 11
  • What is the reason that you insist on trying to find workarounds for restrictions in a particular tool instead of using another tool (apart from openssl ca) without these limitations? – Steffen Ullrich Apr 05 '16 at 13:29
  • @SteffenUllrich what tool can you suggest? I'm open for alternatives. If you're talking about the `openssl ca` tool, then that tool has too many limitations: No simple way without hacks to set a custom serial and an insistence on a file based database. – Danilo Bargen Apr 05 '16 at 13:32
  • I'm usually using the CERT_create function from the perl module [IO::Socket::SSL::Utils](https://metacpan.org/pod/IO::Socket::SSL::Utils) to generate the certificates I need. No CSR needed in this case, no database etc - you have full control. – Steffen Ullrich Apr 05 '16 at 13:34
  • The CSR is provided by the end user. It's needed :) – Danilo Bargen Apr 05 '16 at 13:36
  • I see. Unfortunately at the moment this module can only parse certificates (and re-create new ones from this) but not CSR. – Steffen Ullrich Apr 05 '16 at 13:41
  • Ah, if you want to go the programming route, I can recommend Ruby's built-in OpenSSL bindings. I've used them to make a CA script when I needed to add some extensions that OpenSSL itself didn't support. – user1686 Apr 07 '16 at 17:02

3 Answers3

3

Very late and really ugly, but ... in OpenSSL 1.1.0 (released in 2016, a few months after this Q) up you can accomplish this by going the other direction:

 # extract the pubkey from the real CSR
 openssl req -in realcsr -pubkey -out realpub
 # create a _fake_ CSR with the correct subject and any keypair 
 # (I use a throwaway for simplicity but if you have another you can use that) 
 openssl req -newkey rsa:512 -nodes -keyout fakekey -subj "/C=US/ST=Maine/L=Cabot Cove/CN=Jessica Fletcher" -out fakecsr
 # issue a cert for the subject from the fake CSR but the real pubkey!
 openssl x509 -req -in fakecsr -force_pubkey realpub -CA ca_cert_and_key -out newcert 
 # add other options as needed e.g. -outform pem -$hash -days 30 -set_serial 1234 -extfile extns 
dave_thompson_085
  • 9,759
  • 1
  • 24
  • 28
2

My example:

Generate a self-signed certificate (and private key)

$ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -sha256 -keyout mydomain_rsa.PEM.key -out mydomain.PEM.csr -subj "/C=CN/O=Company Inc."
   Generating a 2048 bit RSA private key  
   ..........................+++  
   ........+++  
   writing new private key to 'mydomain_rsa.PEM.key'  
   -----  

View the subject

$ openssl x509 -noout -serial -subject -in mydomain.PEM.csr
  serial=CCC8F2F4B4BEDBAC
  subject= /C=CN/O=Company Inc.

Modify the subject

openssl req -x509 -in mydomain.PEM.csr -subj '/O=Company2 Inc.' -key mydomain_rsa.PEM.key -out new_mydomain.PEM.csr

View the subject of the new certificate

$ openssl x509 -noout -serial -subject -in new_mydomain.PEM.csr
  serial=A873BD71BCD0DFF7
  subject= /O=Company2 Inc
user155678
  • 29
  • 2
0

My example:

The first certificate with a new private key

openssl req -new -newkey rsa:2048 -nodes -sha256 -days 365 -keyout certificateExample.key -out certificateExample.csr
openssl x509 -req -in certificateExample.csr -signkey certificateExample.key -out certificateExample.cer

The second certificate, with the old private key

openssl req -new -sha256 -days 365 -key certificateExample.key -subj /O=Contoso -out certificateExampleContoso.csr
openssl x509 -req -in certificateExampleContoso.csr -signkey certificateExample.key -out certificateExampleContoso.cer

To view the subject names

openssl x509 -noout -serial -subject -in certificateExampleContoso.cer
serial=C6E02EB9402CEABD
subject=O = Contoso

The key is to generate a new certificate signing request (CSR) with the new subject name. As the CSR itself is signed, you cannot "transform" an old CSR into a new CSR with a different subject name. That's why I generated a new CSR with the new subject name.

  • That only works for the private key owner, i.e. the cert requester (aka applicant aka subscriber), not the CA, which is what this Q wants. – dave_thompson_085 Jun 26 '19 at 03:21