Hi All,
I have a requirement to get unique certificate for each user.
To achieve that I am modifying the CN field of CERT subject name by appending
the user index to CN field.
Eg.
If CN=sanjay
For userIndex 1, I want to modify it like CN=sanjay000001, considering the user
count to 1 Lakh.
I have the below code to achieve the above requirement.
But I am memory dump in below line:
if (!X509_NAME_add_entry(target_sub_name, target_entry, -1,
0))
{
LOG_EVENT(LOG_LEVEL_ERROR, FACILITY_IKEV2, "Failed
adding entry to certificate");
}
.
Seems it this doesn't allow to increment the length of CN field(look like array
overflow).
Any help to achieve the above requirement or any other way of doing the same ?
Thanks,
Sanjay
Function used to modify the CN field in certificate:
int Certificateclass::generate_cert(X509 *x509, uint32_t user_id, uint8_t
**user_cert, EVP_PKEY *cakey, uint32_t usr_cert_len)
{
unsigned char *ptr = NULL, *temp = NULL, target_cn_value[EAY_MAX_CN_LEN] =
{'\0'};
int len = 0, nid = 0;
uint8_t entry_count = 0, i = 0;
char sub_name_str[EAY_MAX_CN_LEN] = {'\0'}; /*used for logging purpose*/
X509_NAME *base_sub_name = NULL, *target_sub_name = NULL;
X509_NAME_ENTRY *entry = NULL, *target_entry = NULL;
ASN1_OBJECT *entry_obj = NULL;
ASN1_STRING *entry_string = NULL;
char *dataStart = NULL;
long nameLength = 0;
BIO *subjectBio = BIO_new(BIO_s_mem());
char temp_cn[EAY_MAX_CN_LEN]= {'\0'};
base_sub_name = X509_get_subject_name(x509);
entry_count = X509_NAME_entry_count(base_sub_name);
target_sub_name = X509_NAME_new();
X509_NAME_print_ex(subjectBio, base_sub_name, 0, XN_FLAG_ONELINE);
nameLength = BIO_get_mem_data(subjectBio, &dataStart);
memcpy(sub_name_str, dataStart, nameLength);
sub_name_str[nameLength] = '\0';
for (i = 0; i < entry_count; i++)
{
entry = X509_NAME_get_entry(base_sub_name, i); /*Get all element from
cert sub name*/
if (entry)
{
entry_obj = X509_NAME_ENTRY_get_object(entry);
if (entry_obj)
{
nid = OBJ_obj2nid(entry_obj);
if (NID_commonName == nid)
{
/* if entry NID is CN then append user index, else simply
add to target_sub_name */
if( NULL == commonName)
{
if(NULL != sub_name_str){
LOG_EVENT (LOG_LEVEL_INFO, FACILITY_IKEV2,
"Certificate subject name received:%s", sub_name_str);
}
commonName = (uint8_t *)calloc(1, EAY_MAX_CN_LEN);
X509_NAME_get_text_by_NID(base_sub_name, nid, (char
*)commonName, EAY_MAX_CN_LEN);
}
{
/*Modifying the certificate subject name */
memcpy(temp_cn, commonName, strlen((char *)commonName));
snprintf((char *)target_cn_value, EAY_MAX_CN_LEN,
"%s%06d", temp_cn, user_id);
}
/*adding the new subject to target Enrty*/
target_entry = X509_NAME_ENTRY_create_by_NID(NULL, nid,
MBSTRING_ASC, target_cn_value, -1);
if(NULL == target_entry)
LOG_EVENT(LOG_LEVEL_ERROR, FACILITY_IKEV2, "Failed to
create target_entry, it is NULL");
if (!X509_NAME_add_entry(target_sub_name, target_entry, -1,
0))
{
LOG_EVENT(LOG_LEVEL_ERROR, FACILITY_IKEV2, "Failed
adding entry to certificate");
}
}
else
{
if (!X509_NAME_add_entry(target_sub_name, entry, -1, 0))
{
LOG_EVENT(LOG_LEVEL_ERROR, FACILITY_IKEV2, "Failed
adding entry to certificate");
}
}
}
}
}
X509_set_subject_name(x509, target_sub_name);
BIO_free(subjectBio);
subjectBio = BIO_new(BIO_s_mem());
X509_NAME_print_ex(subjectBio, target_sub_name, 0, XN_FLAG_ONELINE);
nameLength = BIO_get_mem_data(subjectBio, &dataStart);
memcpy(sub_name_str, dataStart, nameLength);
sub_name_str[nameLength] = '\0';
if(NULL != sub_name_str)
{
LOG_EVENT (LOG_LEVEL_INFO, FACILITY_IKEV2, "Certificate subject name
updated to:%s for user_id:%d", sub_name_str, user_id);
}
X509_NAME_free(target_sub_name);
BIO_free(subjectBio);
if (!(X509_sign(x509, cakey, EVP_sha1())))
{
LOG_EVENT(LOG_LEVEL_ERROR, FACILITY_IKEV2, "failed to sign the
certificate");
return 0;
}
*user_cert= (unsigned char *) calloc(1, usr_cert_len + 1);
ptr = *user_cert;
temp = ptr;
i2d_X509(x509,(unsigned char **)&ptr);
len = (ptr - temp);
return len;
}