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