/usr/share/gocode/src/github.com/docker/libtrust/certificates.go is in golang-github-docker-libtrust-dev 0.0~git20150526.0.9cbd2a1-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 | package libtrust
import (
"crypto/rand"
"crypto/x509"
"crypto/x509/pkix"
"encoding/pem"
"fmt"
"io/ioutil"
"math/big"
"net"
"time"
)
type certTemplateInfo struct {
commonName string
domains []string
ipAddresses []net.IP
isCA bool
clientAuth bool
serverAuth bool
}
func generateCertTemplate(info *certTemplateInfo) *x509.Certificate {
// Generate a certificate template which is valid from the past week to
// 10 years from now. The usage of the certificate depends on the
// specified fields in the given certTempInfo object.
var (
keyUsage x509.KeyUsage
extKeyUsage []x509.ExtKeyUsage
)
if info.isCA {
keyUsage = x509.KeyUsageCertSign
}
if info.clientAuth {
extKeyUsage = append(extKeyUsage, x509.ExtKeyUsageClientAuth)
}
if info.serverAuth {
extKeyUsage = append(extKeyUsage, x509.ExtKeyUsageServerAuth)
}
return &x509.Certificate{
SerialNumber: big.NewInt(0),
Subject: pkix.Name{
CommonName: info.commonName,
},
NotBefore: time.Now().Add(-time.Hour * 24 * 7),
NotAfter: time.Now().Add(time.Hour * 24 * 365 * 10),
DNSNames: info.domains,
IPAddresses: info.ipAddresses,
IsCA: info.isCA,
KeyUsage: keyUsage,
ExtKeyUsage: extKeyUsage,
BasicConstraintsValid: info.isCA,
}
}
func generateCert(pub PublicKey, priv PrivateKey, subInfo, issInfo *certTemplateInfo) (cert *x509.Certificate, err error) {
pubCertTemplate := generateCertTemplate(subInfo)
privCertTemplate := generateCertTemplate(issInfo)
certDER, err := x509.CreateCertificate(
rand.Reader, pubCertTemplate, privCertTemplate,
pub.CryptoPublicKey(), priv.CryptoPrivateKey(),
)
if err != nil {
return nil, fmt.Errorf("failed to create certificate: %s", err)
}
cert, err = x509.ParseCertificate(certDER)
if err != nil {
return nil, fmt.Errorf("failed to parse certificate: %s", err)
}
return
}
// GenerateSelfSignedServerCert creates a self-signed certificate for the
// given key which is to be used for TLS servers with the given domains and
// IP addresses.
func GenerateSelfSignedServerCert(key PrivateKey, domains []string, ipAddresses []net.IP) (*x509.Certificate, error) {
info := &certTemplateInfo{
commonName: key.KeyID(),
domains: domains,
ipAddresses: ipAddresses,
serverAuth: true,
}
return generateCert(key.PublicKey(), key, info, info)
}
// GenerateSelfSignedClientCert creates a self-signed certificate for the
// given key which is to be used for TLS clients.
func GenerateSelfSignedClientCert(key PrivateKey) (*x509.Certificate, error) {
info := &certTemplateInfo{
commonName: key.KeyID(),
clientAuth: true,
}
return generateCert(key.PublicKey(), key, info, info)
}
// GenerateCACert creates a certificate which can be used as a trusted
// certificate authority.
func GenerateCACert(signer PrivateKey, trustedKey PublicKey) (*x509.Certificate, error) {
subjectInfo := &certTemplateInfo{
commonName: trustedKey.KeyID(),
isCA: true,
}
issuerInfo := &certTemplateInfo{
commonName: signer.KeyID(),
}
return generateCert(trustedKey, signer, subjectInfo, issuerInfo)
}
// GenerateCACertPool creates a certificate authority pool to be used for a
// TLS configuration. Any self-signed certificates issued by the specified
// trusted keys will be verified during a TLS handshake
func GenerateCACertPool(signer PrivateKey, trustedKeys []PublicKey) (*x509.CertPool, error) {
certPool := x509.NewCertPool()
for _, trustedKey := range trustedKeys {
cert, err := GenerateCACert(signer, trustedKey)
if err != nil {
return nil, fmt.Errorf("failed to generate CA certificate: %s", err)
}
certPool.AddCert(cert)
}
return certPool, nil
}
// LoadCertificateBundle loads certificates from the given file. The file should be pem encoded
// containing one or more certificates. The expected pem type is "CERTIFICATE".
func LoadCertificateBundle(filename string) ([]*x509.Certificate, error) {
b, err := ioutil.ReadFile(filename)
if err != nil {
return nil, err
}
certificates := []*x509.Certificate{}
var block *pem.Block
block, b = pem.Decode(b)
for ; block != nil; block, b = pem.Decode(b) {
if block.Type == "CERTIFICATE" {
cert, err := x509.ParseCertificate(block.Bytes)
if err != nil {
return nil, err
}
certificates = append(certificates, cert)
} else {
return nil, fmt.Errorf("invalid pem block type: %s", block.Type)
}
}
return certificates, nil
}
// LoadCertificatePool loads a CA pool from the given file. The file should be pem encoded
// containing one or more certificates. The expected pem type is "CERTIFICATE".
func LoadCertificatePool(filename string) (*x509.CertPool, error) {
certs, err := LoadCertificateBundle(filename)
if err != nil {
return nil, err
}
pool := x509.NewCertPool()
for _, cert := range certs {
pool.AddCert(cert)
}
return pool, nil
}
|