hi, i finally got this thing working. that is, i have added custom extensions to certificates. i will try to explain, as well as i can, how i did it.
thanks to everyone that has helped me. --------- Adding custom extensions to certificates ======================================== Note: The code provided in this document does not compile without some really simple modifications. First we need to create a new extension identifier (object identifier, OID) that will identify the extension. The OID is expressed in OpenSSL by the ASN1_OBJECT structure. In OpenSSL we create a new OID like this: /** * First field is the OID itself, which will be converted to DER * encoding. Next fields are the short and long description of * this OID. * Note that the descriptions will not be included as the * extension identifier, but the DER encoding of the OID. */ int nid = OBJ_create("1.2.3.4", "TestOID", "Long description TesT OID"); ASN1_OBJECT* obj = OBJ_nid2obj(nid); OpenSSL has an static array of all available OIDs. Once you create a new OID, as we did in the lines avobe, a new OID is added to OpenSSL, so one can have access to the decriptions. Next step is to create our custom X509 extension identified by the OID created earlier. The basic fields of an X509 extension are: the OID, a boolean saying whether the extension is critical or not, and the extension data. When an extension is critical it can not be read by applications who do not know anything about it. so in our case we should turn it to non-critical. Here is how we create our extension: /* Create data to be included in the extension */ ASN1_OCTET_STRING* data = ::ASN1_OCTET_STRING_new(); ASN1_OCTET_STRING_set(data, "our data", -1); /** * This will create our new extension, identified by our OID (obj * parameter). And with the data created above (data * parameter). The 0 means that the extension is non-critical. */ X509_EXTENSION* ext = X509_EXTENSION_create_by_OBJ(NULL, obj, 0, data); Once we have our extension, we will have to include it to a CSR (Certificate Signing Request), so the CA that creates our certificate will include it to it. We will comment how to add new extension using OpenSSL commands. /** * Create a stack of X509_EXTENSION to add to our request. */ STACK_OF(X509_EXTENSION)* exts = sk_X509_EXTENSION_new_null(); sk_X509_EXTENSION_push(exts, ext); /** * Add the extensions to our CSR. Here it is supposed that the * CSR has been created previously. */ X509_REQ_add_extensions(req, exts); We can make sure that the extensions have been added to the request, by listing them with the follwing code: /** * We need to create our custom OID in order for OpenSSL to found * the short and long descriptions. */ int nid = OBJ_create("1.2.3.4", "TestOID", "Long description TesT OID"); ASN1_OBJECT* obj = OBJ_nid2obj(nid); /** * Here we get the list of available extensions and iterate * through them. */ STACK_OF(X509_EXTENSION)* exts = X509_REQ_get_extensions(req); int n = sk_X509_EXTENSION_num(exts); printf("Extensions: %d\n", n); for (int i = 0; i < n; ++i) { X509_EXTENSION* ext = sk_X509_EXTENSION_value(exts, i); nid = OBJ_obj2nid(ext->object); printf("short name: %-22s - long name: %s\n", OBJ_nid2sn(nid), OBJ_nid2ln(nid)); } As I have said before, we need to create our OID in order to view the descriptions of the extension's OID. That is because the descriptions are not included as part of the OID in the extension. The rest of the code is easy to understand. Now that we have verified that our own extension is inside the CSR, it is time for the CA to create and sign our certificate and to include the extra extensions found in the CSR to it. For this, we now must use the commands provided by OpenSSL. In this case we will use the "ca" command to create the certificate. The "x509" command can also be used to create certificates from CSR, but it will be unable to add extra extensions, so we can not use it for our purpose. As i have said, we will use the "ca" command. In the OpenSSL configuration file, there is a section to configure CA parameters. One of these parameters is "copy_extensions". In our case, we need to set this parameter to "copy", which means the CA will copy all extension present in the CSR to the certificate being created. copy_extensions = copy You can find more information on CA parameters in the next URL: http://www.openssl.org/docs/apps/ca.html#CONFIGURATION_FILE_OPTIONS Next step is to finally create the certificate. Is as easy as this: openssl ca -cert ca.pem -keyfile ca-prikey.pem -outdir . -out certificate.pem -extensions usr_cert -extfile openssl.cnf -infiles request.csr In the command above we just provide the certificate and private key of a CA, two extensions parameters that identifies the extensions to be added to the certificate (not our own extensions), and as a last parameter our CSR. This will create our certificate with our own extension inside it. For more information of the use of OpenSSL commands check out: http://www.openssl.org/docs/apps/openssl.html We can finally check the existence of our extension in the certificate. This will be done similarly to checking the CSR extensions. Here is the code: /** * We need to create our custom OID in order for OpenSSL to found * the short and long descriptions. */ int nid = OBJ_create("1.2.3.4", "TestOID", "Long description TesT OID"); ASN1_OBJECT* obj = OBJ_nid2obj(nid); /** * Here we get the list of available extensions and iterate * through them. Note the we suppose that the X509 certificate is * already created. */ int n = X509_get_ext_count(cert); printf("Extensions: %d\n", n); for (i = 0; i < n; ++i) { X509_EXTENSION* ext = X509_get_ext(cert, i); nid = OBJ_obj2nid(ext->object); printf("short name: %-22s - long name: %s\n", OBJ_nid2sn(nid), OBJ_nid2ln(nid)); } That's it. I hope this information will help other people adding custom extensions to certificates. Aleix Conchillo Flaque ______________________________________________________________________ OpenSSL Project http://www.openssl.org User Support Mailing List [EMAIL PROTECTED] Automated List Manager [EMAIL PROTECTED]