{"action":"opened","issue":{"url":"https://api.github.com/repos/cloudflare/cfssl/issues/632","repository_url":"https://api.github.com/repos/cloudflare/cfssl","labels_url":"https://api.github.com/repos/cloudflare/cfssl/issues/632/labels{/name}","comments_url":"https://api.github.com/repos/cloudflare/cfssl/issues/632/comments","events_url":"https://api.github.com/repos/cloudflare/cfssl/issues/632/events","html_url":"https://github.com/cloudflare/cfssl/issues/632","id":165523711,"number":632,"title":"domainComponent (DC) RDN not included in subject of signed certificate","user":{"login":"jgehrcke","id":265630,"avatar_url":"https://avatars.githubusercontent.com/u/265630?v=3","gravatar_id":"","url":"https://api.github.com/users/jgehrcke","html_url":"https://github.com/jgehrcke","followers_url":"https://api.github.com/users/jgehrcke/followers","following_url":"https://api.github.com/users/jgehrcke/following{/other_user}","gists_url":"https://api.github.com/users/jgehrcke/gists{/gist_id}","starred_url":"https://api.github.com/users/jgehrcke/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jgehrcke/subscriptions","organizations_url":"https://api.github.com/users/jgehrcke/orgs","repos_url":"https://api.github.com/users/jgehrcke/repos","events_url":"https://api.github.com/users/jgehrcke/events{/privacy}","received_events_url":"https://api.github.com/users/jgehrcke/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":0,"created_at":"2016-07-14T10:00:11Z","updated_at":"2016-07-14T10:00:11Z","closed_at":null,"body":"When cfssl receives a certifcate signing request (CSR) which contains one or multiple `domainComponent` (`DC`) relative distinguished names (RDNs) in the subject, then the subject of the signed certificate emitted by cfssl does not contain those `DC` RDNs.\r\n\r\nSubject text representation of an example CSR:\r\n```\r\n$ openssl req -text -noout -verify -in client_cert.csr \r\nverify OK\r\nCertificate Request:\r\n    Data:\r\n        Version: 0 (0x0)\r\n        Subject: CN=readonly, DC=los-pollos, DC=io\r\n[...]\r\n```\r\nNote the subject: `CN=readonly, DC=los-pollos, DC=io`\r\n\r\nAfter sending this CSR to the cfssl `/sign` endpoint, this is the text representation of the cert emitted by cfssl (issuer hidden):\r\n```\r\n$ openssl x509 -in client.crt -text\r\nCertificate:\r\n    Data:\r\n        Version: 3 (0x2)\r\n        Serial Number:\r\n            32:77:f7:7b:9f:e9:f6:a8:24:51:44:66:14:30:3d:38:8d:7b:f4:96\r\n    Signature Algorithm: sha256WithRSAEncryption\r\n        Issuer: C=**, ST=**, L=**, O=**., CN=**\r\n        Validity\r\n            Not Before: Jul 13 13:58:00 2016 GMT\r\n            Not After : Jul 11 13:58:00 2026 GMT\r\n        Subject: CN=readonly\r\n[...]\r\n```\r\nNote how the subject DN was reduced to `CN=readonly`, missing the DC (domainComponent) RDNs.\r\n\r\nMaybe this is a cfssl configuration issue, in which case I'd be happy to receive pointers. Otherwise, this violates [RFC 5280](http://www.ietf.org/rfc/rfc5280.txt) section 4.1.2.4. (page 20):\r\n\r\n> As noted above, distinguished names are composed of attributes.  This\r\n   specification does not restrict the set of attribute types that may\r\n   appear in names.  However, conforming implementations MUST be\r\n   prepared to receive certificates with issuer names containing the set\r\n   of attribute types defined below.  This specification RECOMMENDS\r\n   support for additional attribute types.\r\n[...]\r\n\r\n>  Standard sets of attributes have been defined in the X.500 series of\r\n   specifications [X.520].  Implementations of this specification MUST\r\n   be prepared to receive the following standard attribute types in\r\n   issuer and subject (Section 4.1.2.6) names:\r\n[...]\r\n  **In addition, implementations of this specification MUST be prepared\r\n   to receive the domainComponent attribute, as defined in [RFC4519].**\r\n\r\nBelow you find a self-contained MWE for reproducing.\r\n\r\nMethod:\r\n* Generate CSR is using [Python's cryptography](https://cryptography.io/en/latest/) (w/ OpenSSL bindings).\r\n* Submit CSR to a cfssl instance via [requests](http://docs.python-requests.org/en/master/), receive PEM-serialized signed cert.\r\n* Deserialize cert using cryptography, and print all subject attributes.\r\n\r\nThe output is:\r\n```\r\nSubject attributes:\r\n<NameAttribute(oid=<ObjectIdentifier(oid=2.5.4.3, name=commonName)>, value='readonly')>\r\n```\r\n\r\nThe MWE:\r\n```python\r\nfrom cryptography import x509\r\nfrom cryptography.hazmat.backends import default_backend\r\nfrom cryptography.hazmat.primitives import hashes, serialization\r\nfrom cryptography.hazmat.primitives.asymmetric import rsa\r\nfrom cryptography.x509.oid import NameOID\r\n\r\nimport requests\r\n\r\n\r\ncryptbackend = default_backend()\r\n\r\n\r\n# Create certificate sining request (CSR).\r\nprivate_key = rsa.generate_private_key(\r\n    public_exponent=65537,\r\n    key_size=2048,\r\n    backend=cryptbackend\r\n    )\r\nbuilder = x509.CertificateSigningRequestBuilder()\r\nbuilder = builder.subject_name(x509.Name([\r\n    x509.NameAttribute(NameOID.COMMON_NAME, 'readonly'),\r\n    x509.NameAttribute(NameOID.DOMAIN_COMPONENT, 'los-pollos'),\r\n    x509.NameAttribute(NameOID.DOMAIN_COMPONENT, 'io')\r\n    ]))\r\nbuilder = builder.add_extension(\r\n    x509.BasicConstraints(ca=False, path_length=None),\r\n    critical=True,\r\n).add_extension(\r\n    x509.KeyUsage(\r\n        digital_signature=True,\r\n        content_commitment=False,\r\n        key_encipherment=True,\r\n        data_encipherment=False,\r\n        key_agreement=False,\r\n        key_cert_sign=False,\r\n        crl_sign=False,\r\n        encipher_only=False,\r\n        decipher_only=False\r\n    ),\r\n    critical=False\r\n).add_extension(\r\n    x509.SubjectAlternativeName([x509.DNSName('los-pollos.io')]),\r\n    critical=False\r\n).add_extension(\r\n    x509.SubjectKeyIdentifier.from_public_key(private_key.public_key()),\r\n    critical=False\r\n)\r\n\r\ncsr = builder.sign(private_key, hashes.SHA256(), cryptbackend)\r\ncsr_pem = csr.public_bytes(encoding=serialization.Encoding.PEM).decode('ascii')\r\n\r\nprint(\"CSR:\")\r\nprint(csr_pem)\r\n\r\n\r\n# Send CSR to cfssl.\r\ndata = {\r\n    'certificate_request': csr_pem,\r\n    'profile': '',\r\n    'crl_override': '',\r\n    'label': ''\r\n    }\r\n\r\nr = requests.post(\r\n    url='http://cfsslhost/ca/api/v2/sign',\r\n    headers={'Accept': 'application/json', 'Accept-Charset': 'utf-8'},\r\n    json=data\r\n    )\r\n\r\ncert_pem = r.json()['result']['certificate'].strip() + '\\n'\r\n\r\nprint(\"Cert:\")\r\nprint(cert_pem)\r\n\r\ncert = x509.load_pem_x509_certificate(\r\n    cert_pem.encode('ascii'), cryptbackend)\r\n\r\nprint(\"Subject attributes:\")\r\nfor attr in cert.subject:\r\n    print(attr)\r\n```\r\n"}}
{"actor":{"display_login":"jgehrcke"}}