Tuesday, November 13, 2007

Creating X509 Certificate using OpenSSL Library


OpenSSL Library is a very powerfull Library to Create many other things. From X509 Certificate, Message Signing, Message Encryption and Decryption, and others. And don't forget that OpenSSL library is distributed under Apache Style License. Detail License can be found here.

Below step by step to create Self Sign X509-Certificate:
  1. Initialize X509 Structure, sample:
    X509 *X509Cert = X509_new();

  2. Set X509 Certificate Version:
    X509_set_version(X509Cert, 0x2); // Set to V3

  3. Set Serial Number:
    ASN1_INTEGER_set(X509_get_serialNumber(X509Cert), 1);

  4. Set Issuer Certificate:
    X509_NAME_add_entry_by_txt(X509_get_issuer_name(X509Cert), "C", MBSTRING_ASC, (unsigned char *)"CC", -1, -1, 0);
    X509_NAME_add_entry_by_txt(X509_get_issuer_name(X509Cert), "O", MBSTRING_ASC, (unsigned char *)"Org", -1, -1, 0);
    X509_NAME_add_entry_by_txt(X509_get_issuer_name(X509Cert), "OU", MBSTRING_ASC, (unsigned char *)"OrgUnit", -1, -1, 0);
    X509_NAME_add_entry_by_txt(X509_get_issuer_name(X509Cert), "CN", MBSTRING_ASC, (unsigned char *)"CommonName", -1, -1, 0);

  5. Set Subject Certificate:
    X509_NAME_add_entry_by_txt(X509_get_subject_name(X509Cert), "C", MBSTRING_ASC, (unsigned char *)"CC", -1, -1, 0);
    X509_NAME_add_entry_by_txt(X509_get_subject_name(X509Cert), "O", MBSTRING_ASC, (unsigned char *)"Org", -1, -1, 0);
    X509_NAME_add_entry_by_txt(X509_get_subject_name(X509Cert), "OU", MBSTRING_ASC, (unsigned char *)"OrgUnit", -1, -1, 0);
    X509_NAME_add_entry_by_txt(X509_get_subject_name(X509Cert), "CN", MBSTRING_ASC, (unsigned char *)"CommonName", -1, -1, 0);

  6. Set the Validity of Certificate:
    X509_gmtime_adj(X509_get_notBefore(X509Cert), (long)60*60*24*Days); //Valid From, (start from now)
    X509_gmtime_adj(X509_get_notAfter(X509Cert), (long)60*60*24*Days); //Valid Until (start from now)

  7. Self Sign the Certificate:
    1. Generate RSA Key-pairs:
      EVP_PKEY *pkey = EVP_PKEY_new();
      RSA *rsa = RSA_generate_key(512, 65535, NULL, NULL); //RSA key: 512 bits
      EVP_PKEY_set1_RSA (pkey, rsa);
      X509_set_pubkey(X509Cert, pkey);

    2. Instantiate Digest Algorithm Object (SHA1/ SHA224/ SHA256/ SHA384/ SHA512):
      const EVP_MD *dgAlg = EVP_get_digestbyname("SHA1");

    3. Sign the Certificate:
      X509_sign(X509Cert, pkey, dgAlg);


  8. Save Certificate to File (DER Encoded : .cer):
    BIO *out = BIO_new_file("SampleCert.cer", "w");
    i2d_X509_bio(out, X509Cert);
    BIO_free(out);

  9. Save Corresponding Private Key-pairs to File (DER Encoded : .key):
    BIO *out = BIO_new_file("SampleCert.key", "w");
    i2d_PrivateKey_bio(out, pkey);
    BIO_free(out);

  10. Free up Certificate Variable:
    RSA_free(rsa);
    EVP_PKEY_free(pkey);
    X509_free(X509Cert);

All the code without verifying return value from each function to check whether thu function run successfully or not.

2 comments:

Unknown said...

Just wanted to say a quick thanks for this block of code. I needed to dynamically generate a self-signed certificate within an SSL server. Your post was very clear, easy to use, and was compiling within minutes!

Bhayangkara said...

you're welcome :)
hope this blog, especially this post is help for you and others.