github.com/gramework/gramework@v1.8.1-0.20231027140105-82555c9057f5/tls.go (about)

     1  // Copyright 2017-present Kirill Danshin and Gramework contributors
     2  // Copyright 2019-present Highload LTD (UK CN: 11893420)
     3  //
     4  // Licensed under the Apache License, Version 2.0 (the "License");
     5  // you may not use this file except in compliance with the License.
     6  // You may obtain a copy of the License at
     7  //
     8  //     http://www.apache.org/licenses/LICENSE-2.0
     9  //
    10  
    11  package gramework
    12  
    13  import (
    14  	"crypto/ecdsa"
    15  	"crypto/elliptic"
    16  	"crypto/rand"
    17  	"crypto/tls"
    18  	"crypto/x509"
    19  	"crypto/x509/pkix"
    20  	"fmt"
    21  	"math/big"
    22  	"time"
    23  )
    24  
    25  const localhost = "localhost"
    26  
    27  func selfSignedCertificate(clientHello *tls.ClientHelloInfo) (*tls.Certificate, error) {
    28  	if clientHello.ServerName != localhost {
    29  		return nil, fmt.Errorf("self-signed certificate for %q not permitted", clientHello.ServerName)
    30  	}
    31  
    32  	priv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
    33  	if err != nil {
    34  		return nil, err
    35  	}
    36  
    37  	serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
    38  	serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
    39  	if err != nil {
    40  		return nil, fmt.Errorf("failed to generate serial number: %s", err)
    41  	}
    42  
    43  	template := &x509.Certificate{
    44  		SerialNumber: serialNumber,
    45  		Subject: pkix.Name{
    46  			Organization: []string{"Acme Co"},
    47  		},
    48  
    49  		NotBefore: time.Now(),
    50  		NotAfter:  time.Now().AddDate(0, 1, 0),
    51  
    52  		DNSNames: []string{localhost},
    53  
    54  		KeyUsage:              x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
    55  		ExtKeyUsage:           []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
    56  		BasicConstraintsValid: true,
    57  	}
    58  
    59  	cert, err := x509.CreateCertificate(rand.Reader, template, template, &priv.PublicKey, priv)
    60  	if err != nil {
    61  		return nil, err
    62  	}
    63  
    64  	return &tls.Certificate{
    65  		Certificate: [][]byte{cert},
    66  		PrivateKey:  priv,
    67  	}, nil
    68  }