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 }