5

I need to specify the registeredID in certificate.

So I add this in config file, when sign certificate using OpenSSL.

[ alternate_names ]
DNS.1 = localhost
RID.1 = 1.2.3.4.5.5

Here, 1.2.3.4.5.5 is OID.

I followed How to format an OID Subject Alt Name entry in a openssl.cnf file in Stack Overflow.

Now, I want to generate certificate in Go. Below one is my current config

cfg := cert.Config{
    CommonName:   name,
    Organization: []string{"Elasticsearch Operator"},
    AltNames: cert.AltNames{
        DNSNames: []string{
            "localhost",
        },
    },
    Usages: []x509.ExtKeyUsage{
        x509.ExtKeyUsageServerAuth,
        x509.ExtKeyUsageClientAuth,
    },
}

In this configuration, how can I add OID number.

Shahriar
  • 13,460
  • 8
  • 78
  • 95
  • `DNSNames: []string` seems like it might be too restrictive. [RFC 5280](https://tools.ietf.org/html/rfc5280#section-4.2.1.6) provides more `GeneralNames` than the DNS name. Does Go have other `GeneralNames`, like `iPAddress`, `registeredID` or `rfc822Name`? – jww Feb 16 '18 at 08:52
  • No. I can't see any – Shahriar Feb 16 '18 at 08:56
  • Ouch... It looks like [`CreateCertificateRequest`](https://godoc.org/crypto/x509) and [`Certificate` type](https://golang.org/src/crypto/x509/x509.go#L623) provide some other `GeneralNames` like `EmailAddresses` and `IPAddresses`, but I don't see several of the other ones. Maybe you have to shell-out to the command line. – jww Feb 16 '18 at 09:02

1 Answers1

5

There is no direct way to add OBJECT IDENTIFIER in certificate using Go.

We have found a custom solution.

Go provides an option to add additional SAN information in Certificate

x509.Certificate{
    ExtraExtensions: []pkix.Extension{
        {
            // Here, We add SAN additional with specific ID
        },
    },
}

According to 2.5.29.17 - Subject Alternative Name, OID for SAN is 2.5.29.17

Lets say, we will add registeredID 1.2.3.4.5.5 in SAN. And this RID needs to be added as Tag #8. (According to 2.5.29.17)

So the byte value for this Extension is []byte{0x88, 0x05, 0x2A, 0x03, 0x04, 0x05, 0x05}

Here,

  • 0x88 is the tag value for context-specific #8
  • 0x05 is length of the encoded value
  • 0x2A, 0x03, 0x04, 0x05, 0x05 is encoded value of 1.2.3.4.5.5
    • 0x2A comes from 42 which is 40 * 1 + 2, here 1 and 2 are first two value of ID.

So, finally

rawValue := []asn1.RawValue{
    {FullBytes: []byte{0x88, 0x05, 0x2A, 0x03, 0x04, 0x05, 0x05}},
}
rawByte, _ := asn1.Marshal(rawValue)

_ = x509.Certificate{
    ExtraExtensions: []pkix.Extension{
        {
            Id:    asn1.ObjectIdentifier{2, 5, 29, 17},
            Value: rawByte,
        },
    },
}
Shahriar
  • 13,460
  • 8
  • 78
  • 95
  • 2
    Nice solution. It seems like the long term solution is for Go to support additional `GeneralNames`. – jww Feb 17 '18 at 07:12