Skip to content

Commit 4e52a19

Browse files
authored
Merge pull request #384 from fanminshi/tls_impl
pkg/util/tlsutil: add tls primitives functions
2 parents e222de3 + 69f4285 commit 4e52a19

File tree

2 files changed

+118
-4
lines changed

2 files changed

+118
-4
lines changed

pkg/tlsutil/primitives.go

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
// Copyright 2018 The Operator-SDK Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package tlsutil
16+
17+
import (
18+
"crypto/rand"
19+
"crypto/rsa"
20+
"crypto/x509"
21+
"crypto/x509/pkix"
22+
"encoding/pem"
23+
"fmt"
24+
"math"
25+
"math/big"
26+
"time"
27+
28+
"k8s.io/api/core/v1"
29+
)
30+
31+
const (
32+
rsaKeySize = 2048
33+
duration365d = time.Hour * 24 * 365
34+
)
35+
36+
// newPrivateKey returns randomly generated RSA private key.
37+
func newPrivateKey() (*rsa.PrivateKey, error) {
38+
return rsa.GenerateKey(rand.Reader, rsaKeySize)
39+
}
40+
41+
// encodePrivateKeyPEM encodes the given private key pem and returns bytes (base64).
42+
func encodePrivateKeyPEM(key *rsa.PrivateKey) []byte {
43+
return pem.EncodeToMemory(&pem.Block{
44+
Type: "RSA PRIVATE KEY",
45+
Bytes: x509.MarshalPKCS1PrivateKey(key),
46+
})
47+
}
48+
49+
// encodeCertificatePEM encodes the given certificate pem and returns bytes (base64).
50+
func encodeCertificatePEM(cert *x509.Certificate) []byte {
51+
return pem.EncodeToMemory(&pem.Block{
52+
Type: "CERTIFICATE",
53+
Bytes: cert.Raw,
54+
})
55+
}
56+
57+
// newSelfSignedCACertificate returns a self-signed CA certificate based on given configuration and private key.
58+
// The certificate has one-year lease.
59+
func newSelfSignedCACertificate(key *rsa.PrivateKey) (*x509.Certificate, error) {
60+
serial, err := rand.Int(rand.Reader, new(big.Int).SetInt64(math.MaxInt64))
61+
if err != nil {
62+
return nil, err
63+
}
64+
now := time.Now()
65+
tmpl := x509.Certificate{
66+
SerialNumber: serial,
67+
NotBefore: now.UTC(),
68+
NotAfter: now.Add(duration365d).UTC(),
69+
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
70+
BasicConstraintsValid: true,
71+
IsCA: true,
72+
}
73+
certDERBytes, err := x509.CreateCertificate(rand.Reader, &tmpl, &tmpl, key.Public(), key)
74+
if err != nil {
75+
return nil, err
76+
}
77+
return x509.ParseCertificate(certDERBytes)
78+
}
79+
80+
// newSignedCertificate signs a certificate using the given private key, CA and returns a signed certificate.
81+
// The certificate could be used for both client and server auth.
82+
// The certificate has one-year lease.
83+
func newSignedCertificate(cfg *CertConfig, service *v1.Service, key *rsa.PrivateKey, caCert *x509.Certificate, caKey *rsa.PrivateKey) (*x509.Certificate, error) {
84+
serial, err := rand.Int(rand.Reader, new(big.Int).SetInt64(math.MaxInt64))
85+
if err != nil {
86+
return nil, err
87+
}
88+
eku := []x509.ExtKeyUsage{}
89+
switch cfg.CertType {
90+
case ClientCert:
91+
eku = append(eku, x509.ExtKeyUsageClientAuth)
92+
case ServingCert:
93+
eku = append(eku, x509.ExtKeyUsageServerAuth)
94+
case ClientAndServingCert:
95+
eku = append(eku, x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth)
96+
}
97+
certTmpl := x509.Certificate{
98+
Subject: pkix.Name{
99+
CommonName: cfg.CommonName,
100+
Organization: cfg.Organization,
101+
},
102+
DNSNames: []string{fmt.Sprintf("%s.%s.svc.cluster.local", service.Name, service.Namespace)},
103+
SerialNumber: serial,
104+
NotBefore: caCert.NotBefore,
105+
NotAfter: time.Now().Add(duration365d).UTC(),
106+
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
107+
ExtKeyUsage: eku,
108+
}
109+
certDERBytes, err := x509.CreateCertificate(rand.Reader, &certTmpl, caCert, key.Public(), caKey)
110+
if err != nil {
111+
return nil, err
112+
}
113+
return x509.ParseCertificate(certDERBytes)
114+
}

pkg/tlsutil/tls.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,12 @@ import (
2323
type CertType int
2424

2525
const (
26-
// ClientCert defines a client cert.
27-
ClientCert CertType = iota
26+
// ClientAndServingCert defines both client and serving cert.
27+
ClientAndServingCert CertType = iota
2828
// ServingCert defines a serving cert.
2929
ServingCert
30-
// ClientAndServingCert defines both client and serving cert.
31-
ClientAndServingCert
30+
// ClientCert defines a client cert.
31+
ClientCert
3232
)
3333

3434
// CertConfig configures how to generate the Cert.

0 commit comments

Comments
 (0)