# 证书common name
Date: 2024-07-03


项目自签名证书，common name 超过64个字节报错

```
# openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -sha256 -days 3650 -nodes -subj 
"/C=XX/ST=StateName/L=CityName/O=CompanyName/OU=CompanySectionName/CN=01234567890123456789012345678901234567890123456789012345678901234"
Generating a RSA private key
........................++++
........................................++++
writing new private key to 'key.pem'
-----
problems making Certificate Request
140059529942848:error:0D07A097:asn1 encoding routines:ASN1_mbstring_ncopy:string too long:crypto/asn1/a_mbstr.c:107:maxsize=64

```

 

Common Name在 RFC5280中有描述（https://datatracker.ietf.org/doc/html/rfc5280#appendix-A）

```
-- Naming attributes of type X520CommonName

id-at-commonName        AttributeType ::= { id-at 3 }

-- Naming attributes of type X520CommonName:
-- X520CommonName ::= DirectoryName (SIZE (1..ub-common-name))
--
-- Expanded to avoid parameterized type:
X520CommonName ::= CHOICE {
      teletexString     TeletexString   (SIZE (1..ub-common-name)),
      printableString   PrintableString (SIZE (1..ub-common-name)),
      universalString   UniversalString (SIZE (1..ub-common-name)),
      utf8String        UTF8String      (SIZE (1..ub-common-name)),
      bmpString         BMPString       (SIZE (1..ub-common-name)) }
```

可以看到ub-common-name就是其长度定义， 当然也有一系列定义。

```
-- specifications of Upper Bounds MUST be regarded as mandatory
-- from Annex B of ITU-T X.411 Reference Definition of MTS Parameter
-- Upper Bounds

-- Upper Bounds
ub-name INTEGER ::= 32768
ub-common-name INTEGER ::= 64
ub-locality-name INTEGER ::= 128
ub-state-name INTEGER ::= 128
ub-organization-name INTEGER ::= 64
ub-organizational-unit-name INTEGER ::= 64
ub-title INTEGER ::= 64
ub-serial-number INTEGER ::= 64
ub-match INTEGER ::= 128
ub-emailaddress-length INTEGER ::= 255
ub-common-name-length INTEGER ::= 64
ub-country-name-alpha-length INTEGER ::= 2
ub-country-name-numeric-length INTEGER ::= 3
ub-domain-defined-attributes INTEGER ::= 4
ub-domain-defined-attribute-type-length INTEGER ::= 8
ub-domain-defined-attribute-value-length INTEGER ::= 128
ub-domain-name-length INTEGER ::= 16
ub-extension-attributes INTEGER ::= 256
ub-e163-4-number-length INTEGER ::= 15
ub-e163-4-sub-address-length INTEGER ::= 40
ub-generation-qualifier-length INTEGER ::= 3
ub-given-name-length INTEGER ::= 16
ub-initials-length INTEGER ::= 5
ub-integer-options INTEGER ::= 256
ub-numeric-user-id-length INTEGER ::= 32
ub-organization-name-length INTEGER ::= 64
ub-organizational-unit-name-length INTEGER ::= 32
ub-organizational-units INTEGER ::= 4
ub-pds-name-length INTEGER ::= 16
ub-pds-parameter-length INTEGER ::= 30
ub-pds-physical-address-lines INTEGER ::= 6
ub-postal-code-length INTEGER ::= 16
ub-pseudonym INTEGER ::= 128
ub-surname-length INTEGER ::= 40
ub-terminal-id-length INTEGER ::= 24
ub-unformatted-address-length INTEGER ::= 180
ub-x121-address-length INTEGER ::= 16
```

 

看下openssl中的定义

https://github.com/openssl/openssl/blob/master/crypto/asn1/tbl\_standard.h

```
/* size limits: this stuff is taken straight from RFC3280 */

#define ub_name                         32768
#define ub_common_name                  64
#define ub_locality_name                128
#define ub_state_name                   128
#define ub_organization_name            64
#define ub_organization_unit_name       64
#define ub_title                        64
#define ub_email_address                128
#define ub_serial_number                64

/* From RFC4524 */

#define ub_rfc822_mailbox               256

/* This table must be kept in NID order */

static const ASN1_STRING_TABLE tbl_standard[] = {
    {NID_commonName, 1, ub_common_name, DIRSTRING_TYPE, 0},
    {NID_countryName, 2, 2, B_ASN1_PRINTABLESTRING, STABLE_NO_MASK},
    {NID_localityName, 1, ub_locality_name, DIRSTRING_TYPE, 0},
    {NID_stateOrProvinceName, 1, ub_state_name, DIRSTRING_TYPE, 0},
    {NID_organizationName, 1, ub_organization_name, DIRSTRING_TYPE, 0},
。。。。
```

 

调用链， 最终ASN1\_mbstring\_ncopy处理时判断common name的长度。

```
main()
  |
  └──> do_cmd()
        |
        └──> req_main()
              |
              └──> X509_REQ_new()
              |
              └──> X509_REQ_set_subject_name()
                    |
                    └──> X509_NAME_add_entry_by_txt()
                          |
                          └──> ASN1_mbstring_copy()
                                |
                                └──> ASN1_mbstring_ncopy()

```

 

另外再查看源码，没看到从main直接调用 req\_main, 这部分openssl使用脚本，https://github.com/openssl/openssl/blob/master/apps/progs.pl  自动生成代码， 其中包含一个functions的数组，通过prog\_init初始化hash表， do\_cmd 函数会调用 `lh_FUNCTION_retrieve` 来从哈希表中检索命令处理函数。

 

图片from[**陳柏濡**](https://www.facebook.com/groups/474930279315210/user/100000060530795/?__cft__[0]=AZVbogpHR9x1k6CXXz6Qn-VKJWCVNP_QVu4Tg1gDNP7ObztpIWqBfNgsYgfOGU9S8u1vJ1QxGm8XV0yAP0xzb2ClkGVk_Ihrf6HUx3Ec3mOsuYCoiVB3AB3DjXSFRbWFpCID-76JmWeGWZ_i_NFNjLXLzO7a3DdUkOQxxLnEIRwClA_4ClIpy8rmcC7yStddQDgqiSVEHS5c74nibvp0Mp1o&__tn__=-UC%2CP-R)

