github.com/amp-space/amp-sdk-go@v0.7.6/stdlib/utils/certs.go (about)

     1  package utils
     2  
     3  import (
     4  	"crypto/ecdsa"
     5  	"crypto/elliptic"
     6  	"crypto/rand"
     7  	"crypto/rsa"
     8  	"crypto/tls"
     9  	"crypto/x509"
    10  	"crypto/x509/pkix"
    11  	"encoding/hex"
    12  	"encoding/pem"
    13  	"fmt"
    14  	"math/big"
    15  	"net"
    16  	"os"
    17  	"time"
    18  )
    19  
    20  func MakeSelfSignedX509Certificate() (*tls.Certificate, error) {
    21  	priv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
    22  	if err != nil {
    23  		return nil, err
    24  	}
    25  
    26  	template := x509.Certificate{
    27  		SerialNumber: big.NewInt(1),
    28  		Subject: pkix.Name{
    29  			CommonName: "redwood",
    30  		},
    31  		NotBefore: time.Now(),
    32  		NotAfter:  time.Now().Add(time.Hour * 24 * 180),
    33  
    34  		KeyUsage:              x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
    35  		ExtKeyUsage:           []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
    36  		BasicConstraintsValid: true,
    37  		IsCA:                  true,
    38  
    39  		IPAddresses: []net.IP{net.ParseIP("127.0.0.1"), net.ParseIP("10.0.0.2")},
    40  	}
    41  
    42  	derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, publicKey(priv), priv)
    43  	if err != nil {
    44  		return nil, err
    45  	}
    46  
    47  	var outCert tls.Certificate
    48  	outCert.Certificate = append(outCert.Certificate, derBytes)
    49  	outCert.PrivateKey = priv
    50  	return &outCert, nil
    51  }
    52  
    53  func publicKey(priv interface{}) interface{} {
    54  	switch k := priv.(type) {
    55  	case *rsa.PrivateKey:
    56  		return &k.PublicKey
    57  	case *ecdsa.PrivateKey:
    58  		return &k.PublicKey
    59  	default:
    60  		return nil
    61  	}
    62  }
    63  
    64  func DeviceIDFromX509Pubkey(pubkey interface{}) string {
    65  	switch k := pubkey.(type) {
    66  	case *ecdsa.PublicKey:
    67  		bs := elliptic.MarshalCompressed(k.Curve, k.X, k.Y)
    68  		return hex.EncodeToString(bs)
    69  	case *rsa.PublicKey:
    70  		return ""
    71  	default:
    72  		return ""
    73  	}
    74  }
    75  
    76  func pemBlockForKey(priv interface{}) *pem.Block {
    77  	switch k := priv.(type) {
    78  	case *rsa.PrivateKey:
    79  		return &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(k)}
    80  	case *ecdsa.PrivateKey:
    81  		b, err := x509.MarshalECPrivateKey(k)
    82  		if err != nil {
    83  			fmt.Fprintf(os.Stderr, "Unable to marshal ECDSA private key: %v", err)
    84  			os.Exit(2)
    85  		}
    86  		return &pem.Block{Type: "EC PRIVATE KEY", Bytes: b}
    87  	default:
    88  		return nil
    89  	}
    90  }