I have a C/C++ application and I need to create a X509 pem certificate containing both a public and private key. The certificate can be self signed, or unsigned, doesn't matter.
I want to do this inside an app, not from command line.
What OpenSSL functions will do this for me? Any sample code is a bonus!
Very simple tutorial to create digital certificates http://publib.boulder.ibm.com/infocenter/rsthelp/v8r0m0/index.jsp?topic=/com.ibm.rational.test.lt.doc/topics/tcreatecertopenssl.html
About executing these commands from your code I'm not sure.
I realize that this is a very late (and long) answer. But considering how well this question seems to rank in search engine results, I figured it might be worth writing a decent answer for.
A lot of what you will read below is borrowed from this demo and the OpenSSL docs. The code below applies to both C and C++.
Before we can actually create a certificate, we need to create a private key. OpenSSL provides the
EVP_PKEY
structure for storing an algorithm-independent private key in memory. This structure is declared inopenssl/evp.h
but is included byopenssl/x509.h
(which we will need later) so you don't really need to explicitly include the header.In order to allocate an
EVP_PKEY
structure, we useEVP_PKEY_new
:There is also a corresponding function for freeing the structure -
EVP_PKEY_free
- which accepts a single argument: theEVP_PKEY
structure initialized above.Now we need to generate a key. For our example, we will generate an RSA key. This is done with the
RSA_generate_key
function which is declared inopenssl/rsa.h
. This function returns a pointer to anRSA
structure.A simple invocation of the function might look like this:
If the return value of
RSA_generate_key
isNULL
, then something went wrong. If not, then we now have an RSA key, and we can assign it to ourEVP_PKEY
structure from earlier:The
RSA
structure will be automatically freed when theEVP_PKEY
structure is freed.Now for the certificate itself.
OpenSSL uses the
X509
structure to represent an x509 certificate in memory. The definition for this struct is inopenssl/x509.h
. The first function we are going to need isX509_new
. Its use is relatively straightforward:As was the case with
EVP_PKEY
, there is a corresponding function for freeing the structure -X509_free
.Now we need to set a few properties of the certificate using some
X509_*
functions:This sets the serial number of our certificate to '1'. Some open-source HTTP servers refuse to accept a certificate with a serial number of '0', which is the default. The next step is to specify the span of time during which the certificate is actually valid. We do that with the following two function calls:
The first line sets the certificate's
notBefore
property to the current time. (TheX509_gmtime_adj
function adds the specified number of seconds to the current time - in this case none.) The second line sets the certificate'snotAfter
property to 365 days from now (60 seconds * 60 minutes * 24 hours * 365 days).Now we need to set the public key for our certificate using the key we generated earlier:
Since this is a self-signed certificate, we set the name of the issuer to the name of the subject. The first step in that process is to get the subject name:
If you've ever created a self-signed certificate on the command line before, you probably remember being asked for a country code. Here's where we provide it along with the organization ('O') and common name ('CN'):
(I'm using the value 'CA' here because I'm Canadian and that's our country code. Also note that parameter #4 needs to be explicitly cast to an
unsigned char *
.)Now we can actually set the issuer name:
And finally we are ready to perform the signing process. We call
X509_sign
with the key we generated earlier. The code for this is painfully simple:Note that we are using the SHA-1 hashing algorithm to sign the key. This differs from the
mkcert.c
demo I mentioned at the beginning of this answer, which uses MD5.We now have a self-signed certificate! But we're not done yet - we need to write these files out to disk. Thankfully OpenSSL has us covered there too with the
PEM_*
functions which are declared inopenssl/pem.h
. The first one we will need isPEM_write_PrivateKey
for saving our private key.If you don't want to encrypt the private key, then simply pass
NULL
for the third and fourth parameter above. Either way, you will definitely want to ensure that the file is not world-readable. (For Unix users, this meanschmod 600 key.pem
.)Whew! Now we are down to one function - we need to write the certificate out to disk. The function we need for this is
PEM_write_X509
:And we're done! Hopefully the information in this answer is enough to give you a rough idea of how everything works, although we've barely scratched the surface of OpenSSL.
For those interested in seeing what all of the code above looks like in a real application, I've thrown together a Gist (written in C++) that you can view here.
Any chance of doing this via a
system
call from within your app? Several good reasons for doing this:Licensing: Calling the
openssl
executable arguably separates it from your application and may provide certain advantages. Disclaimer: consult a lawyer on this.Documentation: OpenSSL comes with phenomenal command-line documentation that greatly simplifies a potentially complicated tool.
Testability: you can exercise OpenSSL from the command line until you understand exactly how to create your certs. There are a lot of options; expect to spend about a day on this until you get all the details right. After that, it's trivial to incorporate the command into your app.
If you choose to use the API, check the
openssl-dev
developers' list on www.openssl.org.Good luck!
You'll need to familiarize yourself with the terminology and mechanisms first.
An X.509 certificate, by definition, does not include a private key. Instead, it is a CA-signed version of the public key (along with any attributes the CA puts into the signature). The PEM format really only supports separate storage of the key and the certificate - although you can then concatenate the two.
In any case, you'll need to invoke 20+ different functions of the OpenSSL API to create a key and a self-signed certificate. An example is in the OpenSSL source itself, in demos/x509/mkcert.c
For a more detailed answer, please see Nathan Osman's explanation below.