I'm trying to generate a client certificate using OpenSSL and Go code. I have an OpenSSL script that generates the certificate with the required extensions, and I want to achieve the same result using Go code.
With OpenSSL
options.ext
The options.ext file used by OpenSSL contains the following extensions:
basicConstraints=CA:FALSE
authorityKeyIdentifier=keyid,issuer
subjectKeyIdentifier=hash
keyUsage=digitalSignature
extendedKeyUsage=clientAuth
generate-client-cert.sh
The OpenSSL script I currently have is as follows:
openssl req \
-newkey rsa:2048 \
-keyout cert.crt \
-out cert.csr \
-nodes \
-sha256
openssl x509 \
-req \
-CA ca.crt \
-CAkey ca.key \
-in cert.csr \
-out cert.crt \
-days 365 \
-CAcreateserial \
-extfile options.ext \
-sha256
After generating the certificate, I can use the following command to view its details:
openssl x509 -in cert.crt -text -noout
The resulting certificate has the following structure:
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
xx:xx:xx:xx:xx:xx:xx:xx
Signature Algorithm: sha256WithRSAEncryption
Issuer: CN=xxx
Validity
Not Before: Jan 1 00:00:00 2023 GMT
Not After : Jan 1 00:00:00 2024 GMT
Subject: CN=xxx
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public-Key: (2048 bit)
Modulus:
...
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Basic Constraints:
CA:FALSE
X509v3 Authority Key Identifier:
DirName:CN=xxx
serial:xx:xx:xx:xx:xx:xx:xx:xx
X509v3 Subject Key Identifier:
...
X509v3 Key Usage:
Digital Signature
X509v3 Extended Key Usage:
TLS Web Client Authentication
Signature Algorithm: sha256WithRSAEncryption
it should look like this:
X509v3 Authority Key Identifier:
DirName:CN=xxx
serial:xx:xx:xx:xx:xx:xx:xx:xx
Go code
In my Go code, I'm using the x509 package to generate the certificate. However, I'm unsure how to set the X509v3 Authority Key Identifier extension. Here's the relevant part of my Go code:
import (
"crypto/rand"
"crypto/rsa"
"crypto/sha1"
"crypto/x509"
"crypto/x509/pkix"
"encoding/asn1"
"os"
"time"
)
...
var caCertificate *x509.Certificate
var caPrivateKey *rsa.PrivateKey
var authorityKeyIdentifierValue []byte // how to write this?
template := &x509.Certificate{
Subject: pkix.Name{
CommonName: "xxx",
},
ExtraExtensions: []pkix.Extension{
{
Id: asn1.ObjectIdentifier{2, 5, 29, 35},
Value: authorityKeyIdentifierValue,
},
},
KeyUsage: x509.KeyUsageDigitalSignature,
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
NotBefore: time.Now(),
NotAfter: time.Now().AddDate(0, 0, 365),
IsCA: false,
BasicConstraintsValid: true,
}
privateKey, err := rsa.GenerateKey(rand.Reader, 2048)
if err != nil {
// err
}
certificateBytes, err := x509.CreateCertificate(rand.Reader, template, caCertificate, &privateKey.PublicKey, caPrivateKey)
if err != nil {
// err
}
// out
How to add DirName and serial to X509v3 Authority Key Identifier?
Related
- http://oid-info.com/get/2.5.29.35
- https://github.com/golang/go/issues/47096 (the original question)
When I tried this:
var caPublicKeyBytes []byte
publicKeyHash := (sha1.Sum(caPublicKeyBytes))[:]
var dirName string
authorityKeyIdentifierValue := []byte{0x30, len(publicKeyHash)}
authorityKeyIdentifierValue = append(authorityKeyIdentifierValue, publicKeyHash...)
authorityKeyIdentifierValue = append(authorityKeyIdentifierValue, 0x80, len(dirName))
authorityKeyIdentifierValue = append(authorityKeyIdentifierValue, []byte(dirName)...)
...
The result was:
X509v3 Authority Key Identifier:
0....0...<....).!.r[..F.....".hCN=xxx.....$...D