]> Sergey Matveev's repositories - tofuproxy.git/blob - cmd/certgen/main.go
WARC
[tofuproxy.git] / cmd / certgen / main.go
1 /*
2 tofuproxy -- flexible HTTP/WARC proxy with TLS certificates management
3 Copyright (C) 2021 Sergey Matveev <stargrave@stargrave.org>
4
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, version 3 of the License.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program.  If not, see <http://www.gnu.org/licenses/>.
16 */
17
18 package main
19
20 import (
21         "crypto/ecdsa"
22         "crypto/elliptic"
23         "crypto/rand"
24         "crypto/x509"
25         "crypto/x509/pkix"
26         "encoding/pem"
27         "flag"
28         "io"
29         "log"
30         "math/big"
31         "os"
32         "time"
33 )
34
35 func main() {
36         cn := flag.String("cn", "tofuproxy.localhost", "CommonName")
37         flag.Parse()
38         log.SetFlags(log.Lshortfile)
39
40         prv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
41         if err != nil {
42                 log.Fatalln(err)
43         }
44         pub := prv.Public()
45         notBefore := time.Now()
46         notAfter := notBefore.Add(365 * 24 * time.Hour)
47
48         serialRaw := make([]byte, 16)
49         if _, err = io.ReadFull(rand.Reader, serialRaw); err != nil {
50                 log.Fatalln(err)
51         }
52         serial := big.NewInt(0)
53         serial = serial.SetBytes(serialRaw)
54
55         template := x509.Certificate{
56                 SerialNumber:          serial,
57                 Subject:               pkix.Name{CommonName: *cn},
58                 DNSNames:              []string{*cn},
59                 NotBefore:             notBefore,
60                 NotAfter:              notAfter,
61                 BasicConstraintsValid: true,
62                 IsCA:                  true,
63         }
64         certRaw, err := x509.CreateCertificate(
65                 rand.Reader, &template, &template, pub, prv,
66         )
67         if err != nil {
68                 log.Fatalln(err)
69         }
70         if _, err = x509.ParseCertificate(certRaw); err != nil {
71                 log.Fatalln(err)
72         }
73         pkcs8, err := x509.MarshalPKCS8PrivateKey(prv)
74         if err != nil {
75                 log.Fatalln(err)
76         }
77
78         err = pem.Encode(os.Stdout, &pem.Block{Type: "PRIVATE KEY", Bytes: pkcs8})
79         if err != nil {
80                 log.Fatalln(err)
81         }
82         err = pem.Encode(os.Stdout, &pem.Block{Type: "CERTIFICATE", Bytes: certRaw})
83         if err != nil {
84                 log.Fatalln(err)
85         }
86 }