I am trying to create a certificate signing request in go using the crypto lib. The problem is it generates the CSR with OU separated by +
, i.e.
Subject: O = Example Org, OU = OU1 + OU = OU2, CN = example.com
How can I generate the CSR with OU separated by ,
like
Subject: O = Example Org, OU = OU1, OU = OU2, CN = example.com
Producing OU separated by +
seems to be default behaviour of crypto
lib. Can this be done using crypto lib? If no, then is there any other lib that can generate CSR with OU separated by ,
I tried generating the CSR using below code
package main
import (
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"crypto/x509/pkix"
"encoding/pem"
"fmt"
"os"
)
func main() {
privKey, err := rsa.GenerateKey(rand.Reader, 2048)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
csrTemplate := x509.CertificateRequest{
Subject: pkix.Name{
CommonName: "example.com",
Organization: []string{"Example Org"},
OrganizationalUnit: []string{"OU1", "OU2"},
},
EmailAddresses: []string{"test@example.com"},
}
csrBytes, err := x509.CreateCertificateRequest(rand.Reader, &csrTemplate, privKey)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
csrPem := pem.EncodeToMemory(&pem.Block{
Type: "CERTIFICATE REQUEST",
Bytes: csrBytes,
})
fmt.Println(string(csrPem))
}
Neither the '+' nor the ',' are part of the certificate. It is just what is used when providing a human readable string representation of the certificate request.
In detail: your code just prints out a CSR file in PEM format, not a human readable presentation of the certificate request. Looking at this CSR with asn1parse gives:
$ openssl asn1parse -in csr.pem
...
37:d=4 hl=2 l= 10 cons: SEQUENCE
39:d=5 hl=2 l= 3 prim: OBJECT :organizationalUnitName
44:d=5 hl=2 l= 3 prim: PRINTABLESTRING :OU1
49:d=4 hl=2 l= 10 cons: SEQUENCE
51:d=5 hl=2 l= 3 prim: OBJECT :organizationalUnitName
56:d=5 hl=2 l= 3 prim: PRINTABLESTRING :OU2
61:d=3 hl=2 l= 20 cons: SET
So, these are separate objects and not a combined string with a '+' between. This '+' instead comes when displaying the certificate request using req:
$ openssl req -in csr.pem -text
Certificate Request:
Data:
Version: 1 (0x0)
Subject: O = Example Org, OU = OU1 + OU = OU2, CN = example.com
Which separator is used here can actually be kind of configured. See openssl-namedisplay-options and look for sep_comma_plus_space
, which is the default separator. To cite the documentation:
The first word is used between the Relative Distinguished Names (RDNs) and the second is between multiple Attribute Value Assertions (AVAs). Multiple AVAs are very rare and their use is discouraged.
So there you have it: a comma is used between different RDN (i.e. O, OU, CN, ...) while a plus is used between multiple AVA inside the same RDN (like multiple OU). Also, using multiple AVA is discouraged anyway.