Skip to content

Instantly share code, notes, and snippets.

@evantill
Last active January 1, 2022 22:23
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save evantill/ebeb9535458c108e35207e0dbf6fe351 to your computer and use it in GitHub Desktop.
Save evantill/ebeb9535458c108e35207e0dbf6fe351 to your computer and use it in GitHub Desktop.
x509 creation in go with a critical extended flag
/*
from https://golang.org/src/crypto/tls/generate_cert.go
*/
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build ignore
// Generate a self-signed X.509 certificate for a TLS server. Outputs to
// 'cert.pem' and 'key.pem' and will overwrite existing files.
package main
import (
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"crypto/x509/pkix"
"fmt"
"github.com/grantae/certinfo"
"log"
"math/big"
"net"
"time"
"encoding/asn1"
)
func publicKey(priv interface{}) interface{} {
switch k := priv.(type) {
case *rsa.PrivateKey:
return &k.PublicKey
case *ecdsa.PrivateKey:
return &k.PublicKey
default:
return nil
}
}
func criticalTimestamping() (ext pkix.Extension,err error) {
var oidExtensionExtendedKeyUsage= asn1.ObjectIdentifier{2, 5, 29, 37}
var oidExtKeyUsageTimeStamping = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 8}
ext = pkix.Extension{}
ext.Id = oidExtensionExtendedKeyUsage
ext.Critical = true
ext.Value, err = asn1.Marshal([]asn1.ObjectIdentifier{oidExtKeyUsageTimeStamping})
return ext, err
}
func main() {
var (
host = "localhost"
notBefore = time.Now()
notAfter = notBefore.Add(365 * 24 * time.Hour)
)
privateKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
if err != nil {
log.Fatalf("failed to generate private key: %s", err)
}
serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
if err != nil {
log.Fatalf("failed to generate serial number: %s", err)
}
criticalTimestampExt,err := criticalTimestamping()
if err != nil {
log.Fatal("failed to create extension: %s",err)
}
template := x509.Certificate{
SerialNumber: serialNumber,
Subject: pkix.Name{
Organization: []string{"Acme Co"},
},
NotBefore: notBefore,
NotAfter: notAfter,
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageTimeStamping},
BasicConstraintsValid: true,
ExtraExtensions: append([]pkix.Extension{}, criticalTimestampExt),
}
if ip := net.ParseIP(host); ip != nil {
template.IPAddresses = append(template.IPAddresses, ip)
} else {
template.DNSNames = append(template.DNSNames, host)
}
derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, publicKey(privateKey), privateKey)
if err != nil {
log.Fatalf("Failed to create certificate: %s", err)
}
cert, err := x509.ParseCertificate(derBytes)
if err != nil {
log.Fatal(err)
}
// Print the certificate
result, err := certinfo.CertificateText(cert)
if err != nil {
log.Fatal(err)
}
fmt.Print(result)
}
GOROOT=/usr/local/Cellar/go/1.9.1/libexec #gosetup
GOPATH=/Users/xxx/go #gosetup
/usr/local/Cellar/go/1.9.1/libexec/bin/go build -i -o /private/var/folders/s_/kn50fvmn61v53vr7dl60555w0000gn/T/___Helloworld_go /xxx/Helloworld.go #gosetup
/private/var/folders/s_/kn50fvmn61v53vr7dl60555w0000gn/T/___Helloworld_go #gosetup
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 156945250069439809349760344902584329812 (0x76128e40a37f54aa4516d336eb456654)
Signature Algorithm: ECDSA-SHA256
Issuer: O=Acme Co
Validity
Not Before: Oct 14 09:58:55 2017 UTC
Not After : Oct 14 09:58:55 2018 UTC
Subject: O=Acme Co
Subject Public Key Info:
Public Key Algorithm: ECDSA
Public-Key: (256 bit)
X:
e2:52:f3:6d:ca:91:bf:e0:fd:35:ac:4f:d9:cb:cb:
b8:2d:cf:42:c9:47:82:75:f1:71:4d:b4:74:71:e1:
ab:07
Y:
b3:df:8c:47:38:54:d0:58:5c:c1:73:15:2e:4f:e1:
54:0e:95:d9:bf:44:b5:df:e3:97:22:92:9f:14:a0:
ad:de
Curve: P-256
X509v3 extensions:
X509v3 Key Usage: critical
Digital Signature, Key Encipherment
X509v3 Basic Constraints: critical
CA:FALSE
X509v3 Subject Alternative Name:
DNS:localhost
X509v3 Extended Key Usage: critical
Time Stamping
Signature Algorithm: ECDSA-SHA256
30:45:02:21:00:ef:b2:cf:d2:03:a8:57:f4:e5:5e:0f:7d:b8:
7e:26:b7:d9:09:29:5b:c5:4c:16:8d:fd:56:8d:f7:ae:de:ba:
06:02:20:6a:ef:a0:f0:2e:1f:fd:20:2a:67:cc:1d:c3:87:87:
2d:ac:a1:fe:6f:af:2e:26:14:fb:4e:b8:bb:b5:99:f5:7f
Process finished with exit code 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment