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;
}

Reply via email to