• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2020 The BoringSSL Authors
2//
3// Permission to use, copy, modify, and/or distribute this software for any
4// purpose with or without fee is hereby granted, provided that the above
5// copyright notice and this permission notice appear in all copies.
6//
7// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
10// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
12// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
13// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14
15//go:build ignore
16
17// make_basic_constraints.go generates self-signed certificates with the basic
18// constraints extension.
19package main
20
21import (
22	"crypto/ecdsa"
23	"crypto/rand"
24	"crypto/x509"
25	"crypto/x509/pkix"
26	"encoding/pem"
27	"fmt"
28	"math/big"
29	"os"
30	"time"
31)
32
33func main() {
34	key := ecdsaKeyFromPEMOrPanic(keyPEM)
35
36	notBefore, err := time.Parse(time.RFC3339, "2000-01-01T00:00:00Z")
37	if err != nil {
38		panic(err)
39	}
40	notAfter, err := time.Parse(time.RFC3339, "2100-01-01T00:00:00Z")
41	if err != nil {
42		panic(err)
43	}
44
45	baseTemplate := x509.Certificate{
46		SerialNumber:       new(big.Int).SetInt64(1),
47		Subject:            pkix.Name{CommonName: "Basic Constraints"},
48		NotBefore:          notBefore,
49		NotAfter:           notAfter,
50		SignatureAlgorithm: x509.ECDSAWithSHA256,
51	}
52
53	certs := []struct {
54		name                  string
55		basicConstraintsValid bool
56		isCA                  bool
57		maxPathLen            int
58		maxPathLenZero        bool
59	}{
60		{name: "none"},
61		{name: "leaf", basicConstraintsValid: true},
62		{name: "ca", basicConstraintsValid: true, isCA: true},
63		{name: "ca_pathlen_0", basicConstraintsValid: true, isCA: true, maxPathLenZero: true},
64		{name: "ca_pathlen_1", basicConstraintsValid: true, isCA: true, maxPathLen: 1},
65		{name: "ca_pathlen_10", basicConstraintsValid: true, isCA: true, maxPathLen: 10},
66	}
67	for _, cert := range certs {
68		template := baseTemplate
69		template.BasicConstraintsValid = cert.basicConstraintsValid
70		template.IsCA = cert.isCA
71		template.MaxPathLen = cert.maxPathLen
72		template.MaxPathLenZero = cert.maxPathLenZero
73
74		certBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, &key.PublicKey, key)
75		if err != nil {
76			panic(err)
77		}
78
79		certPEM := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: certBytes})
80		if err := os.WriteFile(fmt.Sprintf("basic_constraints_%s.pem", cert.name), certPEM, 0666); err != nil {
81			panic(err)
82		}
83	}
84}
85
86const keyPEM = `-----BEGIN PRIVATE KEY-----
87MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgoPUXNXuH9mgiS/nk
88024SYxryxMa3CyGJldiHymLxSquhRANCAASRKti8VW2Rkma+Kt9jQkMNitlCs0l5
89w8u3SSwm7HZREvmcBCJBjVIREacRqI0umhzR2V5NLzBBP9yPD/A+Ch5X
90-----END PRIVATE KEY-----`
91
92func ecdsaKeyFromPEMOrPanic(in string) *ecdsa.PrivateKey {
93	keyBlock, _ := pem.Decode([]byte(in))
94	if keyBlock == nil || keyBlock.Type != "PRIVATE KEY" {
95		panic("could not decode private key")
96	}
97	key, err := x509.ParsePKCS8PrivateKey(keyBlock.Bytes)
98	if err != nil {
99		panic(err)
100	}
101	return key.(*ecdsa.PrivateKey)
102}
103