]> Sergey Matveev's repositories - tofuproxy.git/blob - x509.go
Raise copyright years
[tofuproxy.git] / x509.go
1 /*
2 tofuproxy -- flexible HTTP/HTTPS proxy, TLS terminator, X.509 TOFU
3              manager, WARC/geminispace browser
4 Copyright (C) 2021-2023 Sergey Matveev <stargrave@stargrave.org>
5
6 This program is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, version 3 of the License.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 */
18
19 package tofuproxy
20
21 import (
22         "crypto"
23         "crypto/ecdsa"
24         "crypto/elliptic"
25         "crypto/rand"
26         "crypto/x509"
27         "crypto/x509/pkix"
28         "log"
29         "math/big"
30         "sync"
31         "time"
32 )
33
34 type Keypair struct {
35         cert *x509.Certificate
36         prv  crypto.PrivateKey
37 }
38
39 var (
40         hostCerts  = make(map[string]*Keypair)
41         hostCertsM sync.Mutex
42         Serial     *big.Int
43 )
44
45 func init() {
46         max := big.NewInt(0)
47         max = max.SetBit(max, 128, 1)
48         var err error
49         Serial, err = rand.Int(rand.Reader, max)
50         if err != nil {
51                 panic(err)
52         }
53 }
54
55 func newKeypair(
56         host string,
57         caCert *x509.Certificate,
58         caPrv crypto.PrivateKey,
59 ) *Keypair {
60         prv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
61         if err != nil {
62                 log.Fatalln(err)
63         }
64         pub := prv.Public()
65         notBefore := time.Now()
66         notAfter := notBefore.Add(24 * time.Hour)
67         Serial = Serial.Add(Serial, big.NewInt(1))
68         template := x509.Certificate{
69                 SerialNumber: Serial,
70                 Subject:      pkix.Name{CommonName: host},
71                 DNSNames:     []string{host},
72                 NotBefore:    notBefore,
73                 NotAfter:     notAfter,
74         }
75         certRaw, err := x509.CreateCertificate(
76                 rand.Reader, &template, caCert, pub, caPrv,
77         )
78         if err != nil {
79                 log.Fatalln(err)
80         }
81         cert, err := x509.ParseCertificate(certRaw)
82         if err != nil {
83                 log.Fatalln(err)
84         }
85         return &Keypair{cert, prv}
86 }