Last active
January 1, 2022 22:23
-
-
Save evantill/ebeb9535458c108e35207e0dbf6fe351 to your computer and use it in GitHub Desktop.
x509 creation in go with a critical extended flag
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
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) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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