1// Copyright 2020 The BoringSSL Authors 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// https://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 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