Open zhou-bin opened 6 years ago
ARM Internal Ref: IOTSSL-2501
Hi @zhou-bin,
thank you for your report.
I studied the code and observed the following:
mbedtls_x509_name / mbedtls_asn1_named_data
(the former is a type synonym for the former) linked list in mbedtls_x509_string_to_names
, the RDNs are stored in the reverse order in the linked list compared to their order within the provided string.mbedtls_x509_name / mbedtls_asn1_named_data
linked list to ASN.1 via mbedtls_x509_write_names
, the linked list is traversed from front to back, but ASN.1 writing works backwards. Hence, the order in which the ASN.1 fields occur is reversed compared to the order of the linked list.Hence, when converting a string-encoded DN to ASN.1, the order of the RDNs is preserved.
mbedtls_x509_name / mbedtls_asn1_named_data
linked list in mbedtls_x509_get_name
, the ASN.1 structure is traversed from front to back, adding new instances of mbedtls_x509_name / mbedtls_asn1_named_data
at the end of the linked list. Hence, the order is kept.mbedtls_x509_name / mbedtls_asn1_named_data
linked list to a string in mbedtls_x509_dn_gets
, the order is kept.Hence, when converting an ASN.1 encoded DN to a string, the order of the RDNs is preserved.
There are two issues here:
ASN1 -> LinkedList
and LinkedList -> String
conversions keep the order, while LinkedList -> ASN1
and String -> LinkedList
reverse it? As long as we are interested solely in the composed conversions ASN1 <-> String
, this is OK as they both keep the order, but the change of order in between should be justified or removed.ASN.1 -> String
reverses the order. This should be confirmed, compared to other implementations such as OpenSSL, and potentially changed.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
cc @mpg - do you remember what was the reason for the (non-)reversal in the DN conversion functions?
Also see #1033 (this comment).
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
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;
}
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.