Reputation: 587
I am setting up a private CA, and I want to interface with it using PHP. I have tried with PHP's built-in openssl library. So I create a CSR, and to sign it I use openssl_csr_sign
.
This does sign the CSR, but that's it. In OpenSSL's CLI it would be something like
openssl x509 -req -days 360 -in file.csr -CA ca.crt -CAkey ca.key ...
Whereas I want something like
openssl ca -cert ca.crt -keyfile ca.key -in file.csr -out file.crt ...
Basically it uses the x509 module to sign it, instead of the ca module. So it doesn't write it into the database specified in openssl.cnf
, it doesn't use or update the serial number; it's more "I trust this guy so I'll sign his public key with my private key" than an actual CA. Is there a way to manage a private CA in PHP, with openssl or not?
Upvotes: 1
Views: 1627
Reputation: 14752
Yes and no.
Despite using a provided openssl.conf file, PHP's OpenSSL extension doesn't automatically manage the certificate database and/or serial numbers, and it doesn't provide any utilities to help with that.
On the other hand, the database itself has a relatively simple format, so you can implement it yourself using the primitive file-system functions. Here are some hints if you actually go with that route:
fgets()
comes handy while parsing it.
fscanf()
looks better at first glance, but it treats all whitespace the same and tabs are an essential part of the format, so ...file()
is even easier, but only for reading. Chances are that you'll need read+write at the same time, and you'll need to obtain a lock on the file to avoid race conditions.$serial = hexdec(file_get_contents($pathToSerial))
, pass that variable to openssl_csr_sign()
and then write sprintf("%X\n", $serial + 1)
to the file.<filename>.old
and then creates an entirely new one as <filename>
. What this means is that any file-system ownership, permissions that give your PHP script access to it are lost whenever you use the CLI tool.
chown
, chmod
instructions) to notify you of that.resource
(which should be closed after use). To throw an exception and close the resources only when necessary, I like to pre-define the variables holding them and use
them in a closure that handles all conditional resource-free routines before throwing an exception.As you can see, it is manageable if you know what you're doing, but it has a lot of gotchas and not really worth it for a simple PoC. Calling the CLI tool via exec()
(and siblings) is a simpler choice.
Upvotes: 2