Mbed-TLS / mbedtls

An open source, portable, easy to use, readable and flexible TLS library, and reference implementation of the PSA Cryptography API. Releases are on a varying cadence, typically around 3 - 6 months between releases.
https://www.trustedfirmware.org/projects/mbed-tls/
Other
5.48k stars 2.59k forks source link

mbedtls Bug: the order of RDNs in Subject DN #2005

Open zhou-bin opened 6 years ago

zhou-bin commented 6 years ago

The order of RDNs in Subject DN maybe have wrong.

e.g. The subject DN is: "CN=Test,OU=DemoA,C=CN" Build the PKCS#10 with mbedtls. cert_req subject_name="CN=Test,OU=DemoA,C=CN" You can get the subject DN in PKCS#10 is: "C=CN,OU=DemoA,CN=Test" The order of RDNs in Subject DN is reversed. I test use openssl and J2EE. There is no problem. I need compatible with openssl and J2EE, I have to deal data(reverse order) before call the mbedtls_x509write_csr_set_subject_name api.

ciarmcom commented 6 years ago

ARM Internal Ref: IOTSSL-2501

hanno-becker commented 6 years ago

Hi @zhou-bin,

thank you for your report.

I studied the code and observed the following:

Hence, when converting a string-encoded DN to ASN.1, the order of the RDNs is preserved.

Hence, when converting an ASN.1 encoded DN to a string, the order of the RDNs is preserved.

There are two issues here:

However, regardless of the previous two issues, I am wondering why you are seeing the reversal you describe. Could you please provide the exact calls you use to (1) create the CSR and (2) view the CSR?

Kind regards, Hanno, Mbed TLS team member

hanno-becker commented 6 years ago

cc @mpg - do you remember what was the reason for the (non-)reversal in the DN conversion functions?

thomas-dee commented 6 years ago

Also see #1033 (this comment).

zhou-bin commented 6 years ago

Hi @hanno-arm, Sorry for my delay in answering you. And sorry my english is so bad. I generate the CSR(PKCS#10) by openssl(X509_NAME_add_entry_by_txt) and mbedtls(mbedtls_x509write_csr_set_subject_name). The subject is: CN = TestCN,OU = TestOU,O = TestO,C = CN

the openssl is output -----BEGIN CERTIFICATE REQUEST----- MIH5MIGhAgEAMD8xCzAJBgNVBAYTAkNOMQ4wDAYDVQQKDAVUZXN0TzEPMA0GA1UE CwwGVGVzdE9VMQ8wDQYDVQQDDAZUZXN0Q04wWTATBgcqhkjOPQIBBggqhkjOPQMB BwNCAARfhunGckaHlmFqG/DbTeny1UHxU5kcCQ4ysAapYU33Ryx4A5/ciQOGYoYH GodoO045bFEM6UnR8zAqz2YHn95PoAAwCQYHKoZIzj0EAQNIADBFAiEAzZJLd5BJ 6Rm+k0zEyQljcm/Oxxn8/Ito6CUXROwH314CIHvqE78prlTyQkN0yl37RF6/lIZW 8zbl3yN7OkMNQEUz -----END CERTIFICATE REQUEST----- the subjectname is CN = TestCN,OU = TestOU,O = TestO,C = CN

the mbedtls is output MIH8MIGhAgEAMD8xDzANBgNVBAMTBlRlc3RDTjEPMA0GA1UECxMGVGVzdE9VMQ4wDAYDVQQKEwVUZXN0TzELMAkGA1UEBhMCQ04wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAASEmga/DBLTpaco3xiDGckS1WI08mnLfi+tLfLfzlWT2a8c8Tv6p0RXj+lZyyQyUkcZKTVnV6Dycu/6qgYol12HoAAwDAYIKoZIzj0EAwIFAANIADBFAiBe1dq2krrxvLGgHH6xuEgrsNLLftMnQ7xJlO/UZDjPDgIhAI3vbui2tTCJEGahL6cjTT9WdZI73QweLKCriEqqWMxb the subjectname is C = CN,O = TestO,OU = TestOU,CN = TestCN

zhou-bin commented 6 years ago

For this problem, I think you can: give up mbedtls_x509write_csr_set_subject_name, and replace with this function: int set_asn1_name_mbedtls(mbedtls_asn1_named_data *head, char subjectName); the demo:

mbedtls_x509write_csr *csrContainer;
returnCode = set_asn1_name_mbedtls(&csrContainer->subject, subjectName);
int set_asn1_name_mbedtls(mbedtls_asn1_named_data **head, char *subjectName)
{
    int returnCode = 0;
    int index = 0;
    char *temp1 = NULL;
    char *temp2 = NULL;
    char *temp3 = NULL; 
    char x509Name[128] = { 0 };
    char oidName[128] = { 0 };
    char oidValue[128] = { 0 };
    char oidString[128] = { 0 };
    mbedtls_asn1_named_data *tempASN1 = NULL;
    mbedtls_asn1_named_data *tempASN1List = NULL;
    mbedtls_asn1_buf oidASN1;
    if ((subjectName == NULL) || (head == NULL))
    {
        return STATUS_SECURITY_ERR_ILLEGAL_ARGUMENT;
    }
    temp2 = subjectName;
    while (1)
    {
        memset(x509Name, 0, sizeof(x509Name));
        memset(oidName, 0, sizeof(oidName));
        memset(oidValue, 0, sizeof(oidValue));
        temp1 = strstr(temp2, ",");     
        //get oid and values
        if (temp1 == NULL)
        {
            anima_vsnprintf(
                            x509Name, 
                            128,
                            "%s",
                            temp2
                            );
        }
        else
        {
            strncpy(x509Name, temp2, temp1 - temp2);
        }
        //get oid 
        temp3 = strstr(x509Name, "=");
        if (temp3 == NULL)
        {
            returnCode = -1;
            break;
        }
        strncpy(oidName, x509Name, temp3 - x509Name);
        strncpy(oidValue, temp3 + 1, strlen(x509Name)-(temp3 - x509Name) - 1);
        rtrim(oidName);
        ltrim(oidName);
        memset(x509Name, 0, sizeof(x509Name));
        index = -1;
        for (int loop = 0; loop < 32; loop++)
        {
            if (x509_attrs[loop].name == NULL)
            {
                index = -1;
                break;
            }
            if (strcmp(oidName, x509_attrs[loop].name) == 0)
            {
                index = loop;
                break;
            }
            else if (strcmpex(oidName, x509_attrs[loop].name) == 0)
            {
                index = loop;
                break;
            }
        }
        if (index == -1)
        {
            for (int loop = 0; loop < 32; loop++)
            {
                oidASN1.len = strlen(x509_attrs[loop].oid);
                oidASN1.p = (char*)x509_attrs[loop].oid;
                returnCode = mbedtls_oid_get_numeric_string(oidString, 128, &oidASN1);
                if (returnCode <= 0)
                {
                    break;
                }
                returnCode = 0;
                if (strcmp(oidString, oidName) == 0)
                {
                    index = loop;
                    break;
                }
            }
            if (index == -1)
            {
                returnCode = -1;
                break;
            }
        }
        tempASN1 = (mbedtls_asn1_named_data*)malloc(sizeof(mbedtls_asn1_named_data));
if (tempASN1 == NULL)
        {}
        tempASN1->next = NULL;
        tempASN1->oid.len = strlen(x509_attrs[index].oid);
        tempASN1->val.len = strlen(oidValue);
        tempASN1->oid.p = malloc(tempASN1->oid.len);
if (tempASN1->oid.p == NULL)
        {}
        tempASN1->val.p = malloc(tempASN1->val.len);
if (tempASN1->val.p == NULL)
        {}
        memcpy(tempASN1->oid.p, x509_attrs[index].oid, tempASN1->oid.len);
        memcpy(tempASN1->val.p, oidValue, tempASN1->val.len);
        if (*head == NULL)
        {
            *head = tempASN1;
        }
        if (tempASN1List != NULL)
        {
            tempASN1List->next = tempASN1;
        }
        tempASN1List = tempASN1;
        if (temp1 == NULL)
        {
            break;
        }
        temp2 = temp1 + 1;      
    }   
        if (returnCode != STATUS_SECURITY_OK)
    {
        mbedtls_asn1_free_named_data_list(head);
        *head = NULL;
    }
    return returnCode;
}