cfssl icon indicating copy to clipboard operation
cfssl copied to clipboard

Unable to set multiple OUs in the "names" field

Open csnook opened this issue 9 years ago • 13 comments

x.509 allows for multiple OU fields, so that certificate ownership can be clearly identified even in very large organizations. It's common to see something like this in the Subject Name:

O="Company", OU="Engineering", OU="Operations", OU="Security"

CFSSL does not support this, which may surprise people who are used to this practice with x.509 certificates. Specifying the OU multiple times[1] silently ignores all but the last value. Specifying an array fails.

If it's possible to handle an array for the OU, that would be great. If not, having an alternative parameter that does accept an array ("OUs"?) would also be fine. If this isn't going to be implemented any time soon, printing a warning about multiple OUs being ignored would be nice, so people understand why they're not getting back the certificate they expect.

[1] https://coreos.com/os/docs/latest/generate-self-signed-certificates.html

csnook avatar Apr 20 '16 21:04 csnook

It's actually possible to use cfssl/csr package to generate a CSR with a subject containing multiple OUs. Here is an example csr_test.json: { "key": { "algo": "ecdsa", "size": 256 }, "names": [ { "C": "US", "L": "San Francisco", "ST": "California", "O": "ACME, Inc.", "OU": "First OU" }, { "OU": "Second OU" } ], "cn": "I heard cn is useless" }

cfssl genkey csr_test.json should give you a csr with multiple OUs. But I found a problem with Go's asn1 parser, which will not parse multiple OUs. In fact we can attempt to parse the resulting CSR with Go's x509.ParseCertificateRequest and it only returns a CSR with single OU, "First OU". Meanwhile, openssl will shows the CSR with multiple OUs.

I would consider to raise an issue with Go's core developer.

lziest avatar May 02 '16 03:05 lziest

@lziest is it possible to use cfssl to generate a certificate with a subject containing multiple OUs? Using the json format above I was able to create a csr with multiple OUs, but the certificate still only contained one of them. I tried generating the certificate with multiple OUs using the gencert and newcert commands.

kochsen avatar Aug 19 '16 12:08 kochsen

you are right, we can generate a PEM-encoded CSR which has multiple OUs, but when we trying to parse that CSR into go structure, we only get the first OU in the structure. And since we sign certificate with go structure (doing verification etc.), the resulting cert has only one OU.

lziest avatar Sep 20 '16 21:09 lziest

This seems to happen for multiple organizations, as well. My use case is that Kubernetes uses the O field to assign Kubernetes user groups, and people can be in more than one group.

jimmycuadra avatar Mar 30 '17 00:03 jimmycuadra

Thanks @jimmycuadra this is exactly what I am trying to do. Got all the way to the CSR and then it failed. Built so much around cfssl, hate to pull it out.

deitch avatar Apr 04 '17 14:04 deitch

@deitch Same! We switched from using the openssl command line tool to cfssl because cfssl's API is nicer, but I'm not sure how to proceed now, cause this bug is actually blocking some use cases for us. I get the sense that cfssl is not updated very often, so it doesn't seem like we can assume it will be fixed anytime soon, especially given the suggestion that the problem lies in Go's ASN.1 parser and not cfssl itself. We may just have to switch back to openssl. :\

jimmycuadra avatar Apr 05 '17 00:04 jimmycuadra

@jimmycuadra yeah. I am loathe to switch off of it, since it is an easier API than openssl, and the cfssl serve is neat (although running over http and not https, and passing a token; ugh), but it is on my list now to get off of it, unfortunately.

deitch avatar Apr 05 '17 11:04 deitch

I went through the example from @lziest above and I was able to create a signed certificate with 2 OU's. I put my steps below (I'm running go version go1.8 darwin/amd64). Is it possible the issue's been fixed?

ca_csr.json:

{
    "cn": "I heard cn is useless",
    "key": {
        "algo": "ecdsa",
        "size": 256
    },
    "names": [
        {
            "C": "US",
            "L": "San Francisco",
            "O": "ACME, Inc.",
            "OU": "First OU",
            "ST": "California"
        },
        {
            "OU": "Second OU"
        }
    ]
}

csr_signee.json:

{
    "cn": "Bob",
    "key": {
        "algo": "ecdsa",
        "size": 256
    },
    "names": [
        {
            "C": "US",
            "L": "Philly",
            "O": "Slack's",
            "OU": "Steaks",
            "ST": "Pennsylvania"
        },
        {
            "OU": "Fries"
        }
    ]
}
$ cfssl gencert -initca ca_csr.json
$ echo -e "-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----\n" > ca.pem
$ echo -e "-----BEGIN EC PRIVATE KEY-----\n...\n-----END EC PRIVATE KEY-----\n" > ca_key.pem
$ cfssl gencert -initca csr_signee.json
$ echo -e "-----BEGIN CERTIFICATE REQUEST-----\n...\n-----END CERTIFICATE REQUEST-----\n" > signee_csr.pem
$ cfssl sign -ca ca.pem -ca-key ca_key.pem signee_csr.pem
$ echo -e "-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----\n" > signed_signee.pem
$ cfssl certinfo -cert signed_signee.pem

That last command gave me this:

{
  "subject": {
    "common_name": "Bob",
    "country": "US",
    "organization": "Slack's",
    "organizational_unit": "Steaks,Fries",
    "locality": "Philly",
    "province": "Pennsylvania",
    "names": [
      "US",
      "Pennsylvania",
      "Philly",
      "Slack's",
      "Steaks",
      "Fries",
      "Bob"
    ]
  },
  "issuer": {
    "common_name": "I heard cn is useless",
    "country": "US",
    "organization": "ACME, Inc.",
    "organizational_unit": "First OU,Second OU",
    "locality": "San Francisco",
    "province": "California",
    "names": [
      "US",
      "California",
      "San Francisco",
      "ACME, Inc.",
      "First OU",
      "Second OU",
      "I heard cn is useless"
    ]
  },
  "serial_number": "77888877478957473953290554776194418363091613331",
  "not_before": "2017-04-14T22:34:00Z",
  "not_after": "2018-04-14T22:34:00Z",
  "sigalg": "ECDSAWithSHA256",
  "authority_key_id": "79:23:52:E8:8:2C:A9:32:B1:8A:E5:B7:37:62:F4:B6:12:8C:54:83",
  "subject_key_id": "F6:B1:F8:C6:AA:2:B0:53:FA:E7:AF:E1:29:A6:4D:DB:90:33:70:7A",
  "pem": "-----BEGIN CERTIFICATE-----\nMIICizCCAjCgAwIBAgIUDaSodqvHR4ytxNI1jTJbvhVDdpMwCgYIKoZIzj0EAwIw\ngZQxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1T\nYW4gRnJhbmNpc2NvMRMwEQYDVQQKEwpBQ01FLCBJbmMuMSMwDwYDVQQLEwhGaXJz\ndCBPVTAQBgNVBAsTCVNlY29uZCBPVTEeMBwGA1UEAxMVSSBoZWFyZCBjbiBpcyB1\nc2VsZXNzMB4XDTE3MDQxNDIyMzQwMFoXDTE4MDQxNDIyMzQwMFowdDELMAkGA1UE\nBhMCVVMxFTATBgNVBAgTDFBlbm5zeWx2YW5pYTEPMA0GA1UEBxMGUGhpbGx5MRAw\nDgYDVQQKEwdTbGFjaydzMR0wDQYDVQQLEwZTdGVha3MwDAYDVQQLEwVGcmllczEM\nMAoGA1UEAxMDQm9iMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEoXdV4odAuTFx\nHG+Vl1ZEEC/zxzFpjywt4cmaenHLXwNRft3kdZAR1USjsmBEpiJkXgbOBH2lEceO\nn4azgb0UNqN/MH0wDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMB\nBggrBgEFBQcDAjAMBgNVHRMBAf8EAjAAMB0GA1UdDgQWBBT2sfjGqgKwU/rnr+Ep\npk3bkDNwejAfBgNVHSMEGDAWgBR5I1LoCCypMrGK5bc3YvS2EoxUgzAKBggqhkjO\nPQQDAgNJADBGAiEArXbbz563aVJDx+OEtAFUpGxHHhFJf01h2PnpvTkmmOQCIQDt\nhJIHHEL0OP8J0re6nzKX0D/DGJNK/u5nyCmYUQ/HQg==\n-----END CERTIFICATE-----\n"
}

sfurman3 avatar Apr 15 '17 01:04 sfurman3

Yes! I just tried it with cfssl built with Go 1.8.1 and the final signed certificate had all the organizations that were in the CSR!

Would it be possible to release new cfssl binaries to https://pkg.cfssl.org/ and/or https://github.com/cloudflare/cfssl/releases?

jimmycuadra avatar Apr 15 '17 06:04 jimmycuadra

homebrew's cfssl is still compiled against Go 1.7. You can recompile cfssl against Go 1.8:

brew remove cfssl
brew upgrade go
brew install --build-from-source cfssl

Multiple O or OU fields works!

eugene-chow avatar Apr 26 '17 07:04 eugene-chow

That should help.

cloudflare team, can we get the docker image updated? I just pulled it again, ran strings:

$ docker run --rm --entrypoint=strings cfssl/cfssl /go/bin/cfssl | grep 'go1\.'
go1.6.4

1.6.4?

deitch avatar Apr 26 '17 11:04 deitch

When 1.8-built binaries will be released?

kayrus avatar Jun 06 '17 15:06 kayrus

A year old...

deitch avatar May 07 '18 18:05 deitch