Hello as a new user of OpenSSL I've been trying to get
the examples in the OpenSSL book to run.
I currently have a problem with Example 10-6 from the
book. (enclosed)
I need to make these files:
#define CA_FILE "CA.pem"
#define CA_KEY "CAkey.pem"
to work with the program. To make a certificate. Could
someone throw some light on how to make these files at
the openssl command line?
Thanks
Oliver Foden
________________________________________________________________________
Want to chat instantly with your online friends? Get the FREE Yahoo!
Messenger http://uk.messenger.yahoo.com/
#include <stdio.h>
#include <stdlib.h>
#include <openssl/ssl.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#include <openssl/err.h>
#include <openssl/pem.h>
#include <openssl/rand.h>
#include <openssl/evp.h>
#include <openssl/objects.h>
/*
void seed_prng(void)
{
RAND_load_file("/dev/urandom", 1024);
}*/
void
handle_error (const char *file, int lineno, const char *msg)
{
fprintf (stderr, "** %s:%i %s\n", file, lineno, msg);
ERR_print_errors_fp (stderr);
exit (-1);
}
#define int_error(msg) handle_error(__FILE__, __LINE__, msg)
/* these are defintions to make the example simpler */
#define CA_FILE "CA.pem"
#define CA_KEY "CAkey.pem"
#define REQ_FILE "newreq.pem"
#define CERT_FILE "newcert.pem"
#define DAYS_TILL_EXPIRE 365
#define EXPIRE_SECS (60*60*24*DAYS_TILL_EXPIRE)
#define EXT_COUNT 5
struct entry
{
char *key;
char *value;
};
struct entry ext_ent[EXT_COUNT] = {
{"basicConstraints", "CA:FALSE"},
{"nsComment", "\"OpenSSL Generated Certificate\""},
{"subjectKeyIdentifier", "hash"},
{"authorityKeyIdentifier", "keyid,issuer:always"},
{"keyUsage", "nonRepudiation,digitalSignature,keyEncipherment"}
};
int
main (int argc, char *argv[])
{
int i, subjAltName_pos;
long serial = 1;
EVP_PKEY *pkey, *CApkey;
const EVP_MD *digest;
X509 *cert, *CAcert;
X509_REQ *req;
X509_NAME *name;
X509V3_CTX ctx;
X509_EXTENSION *subjAltName;
STACK_OF (X509_EXTENSION) * req_exts;
FILE *fp;
BIO *out;
/*OpenSSL_add_all_algorithms ();*/
ERR_load_crypto_strings ();
/*seed_prng ();*/
/* open stdout */
if (!(out = BIO_new_fp (stdout, BIO_NOCLOSE)))
int_error ("Error creating stdout BIO");
/* read in the request */
if (!(fp = fopen (REQ_FILE, "r")))
int_error ("Error reading request file");
if (!(req = PEM_read_X509_REQ (fp, NULL, NULL, NULL)))
int_error ("Error reading request in file");
fclose (fp);
/* verify signature on the request */
if (!(pkey = X509_REQ_get_pubkey (req)))
int_error ("Error getting public key from request");
if (X509_REQ_verify (req, pkey) != 1)
int_error ("Error verifying signature on certificate");
/*In Example 10-6 on line 77 (third line of code from bottom of the page),
the parentheses do not match up. The line should rather be:
if (X509_REQ_verify(req, pkey) != 1) */
/* read in the CA certificate */
if (!(fp = fopen (CA_FILE, "r")))
int_error ("Error reading CA certificate file");
if (!(CAcert = PEM_read_X509 (fp, NULL, NULL, NULL)))
int_error ("Error reading CA certificate in file");
fclose (fp);
/* read in the CA private key */
if (!(fp = fopen (CA_KEY, "r")))
int_error ("Error reading CA private key file");
if (!(CApkey = PEM_read_PrivateKey (fp, NULL, NULL, "password")))
int_error ("Error reading CA private key in file");
fclose (fp);
/* print out the subject name and subject alt name extension */
if (!(name = X509_REQ_get_subject_name (req)))
int_error ("Error getting subject name from request");
X509_NAME_print (out, name, 0);
fputc ('\n', stdout);
if (!(req_exts = X509_REQ_get_extensions (req)))
int_error ("Error getting the request's extensions");
subjAltName_pos = X509v3_get_ext_by_NID (req_exts,
OBJ_sn2nid ("subjectAltName"), -1);
subjAltName = X509v3_get_ext (req_exts, subjAltName_pos);
X509V3_EXT_print (out, subjAltName, 0, 0);
fputc ('\n', stdout);
/* WE SHOULD NOW ASK WHETHER TO CONTINUE OR NOT */
/* create new certificate */
if (!(cert = X509_new ()))
int_error ("Error creating X509 object");
/* set version number for the certificate (X509v3) and the serial number */
if (X509_set_version (cert, 2L) != 1)
int_error ("Error settin certificate version");
ASN1_INTEGER_set (X509_get_serialNumber (cert), serial++);
/* set issuer and subject name of the cert from the req and the CA */
if (!(name = X509_REQ_get_subject_name (req)))
int_error ("Error getting subject name from request");
if (X509_set_subject_name (cert, name) != 1)
int_error ("Error setting subject name of certificate");
if (!(name = X509_get_subject_name (CAcert)))
int_error ("Error getting subject name from CA certificate");
if (X509_set_issuer_name (cert, name) != 1)
int_error ("Error setting issuer name of certificate");
/* set public key in the certificate */
if (X509_set_pubkey (cert, pkey) != 1)
int_error ("Error setting public key of the certificate");
/* set duration for the certificate */
if (!(X509_gmtime_adj (X509_get_notBefore (cert), 0)))
int_error ("Error setting beginning time of the certificate");
if (!(X509_gmtime_adj (X509_get_notAfter (cert), EXPIRE_SECS)))
int_error ("Error setting ending time of the certificate");
/* add x509v3 extensions as specified */
X509V3_set_ctx (&ctx, CAcert, cert, NULL, NULL, 0);
for (i = 0; i < EXT_COUNT; i++)
{
X509_EXTENSION *ext;
if (!(ext = X509V3_EXT_conf (NULL, &ctx,
ext_ent[i].key, ext_ent[i].value)))
{
fprintf (stderr, "Error on \"%s = %s\"\n",
ext_ent[i].key, ext_ent[i].value);
int_error ("Error creating X509 extension object");
}
if (!X509_add_ext (cert, ext, -1))
{
fprintf (stderr, "Error on \"%s = %s\"\n",
ext_ent[i].key, ext_ent[i].value);
int_error ("Error adding X509 extension to certificate");
}
X509_EXTENSION_free (ext);
}
/* add the subjectAltName in the request to the cert */
if (!X509_add_ext (cert, subjAltName, -1))
int_error ("Error adding subjectAltName to certificate");
/* sign the certificate with the CA private key */
if (EVP_PKEY_type (CApkey->type) == EVP_PKEY_DSA)
digest = EVP_dss1 ();
else if (EVP_PKEY_type (CApkey->type) == EVP_PKEY_RSA)
digest = EVP_sha1 ();
else
int_error ("Error checking CA private key for a valid digest");
if (!(X509_sign (cert, CApkey, digest)))
int_error ("Error signing certificate");
/* write the completed certificate */
if (!(fp = fopen (CERT_FILE, "w")))
int_error ("Error writing to certificate file");
if (PEM_write_X509 (fp, cert) != 1)
int_error ("Error while writing certificate");
fclose (fp);
return 0;
}