Skip to content

Commit 6f99e24

Browse files
authored
Merge pull request #11 from mengqiy/certprovisioner
move certprovisioner pkg
2 parents 9eef00b + 1990245 commit 6f99e24

File tree

5 files changed

+216
-0
lines changed

5 files changed

+216
-0
lines changed
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/*
2+
Copyright 2018 The Kubernetes Authors.
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+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package certprovisioner
18+
19+
// Certs hosts a private key, its corresponding serving certificate and
20+
// the CA certificate that signs the serving certificate.
21+
type Certs struct {
22+
Key []byte
23+
Cert []byte
24+
CACert []byte
25+
}
26+
27+
// CertProvisioner is an interface to provision the serving certificate.
28+
type CertProvisioner interface {
29+
// ProvisionServingCert returns a Certs struct.
30+
ProvisionServingCert() (*Certs, error)
31+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/*
2+
Copyright 2018 The Kubernetes Authors.
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+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package certprovisioner
18+
19+
import "fmt"
20+
21+
func ExampleServiceToCommonName() {
22+
fmt.Println(ServiceToCommonName("myservicenamespace", "myservicename"))
23+
// Output: myservicename.myservicenamespace.svc
24+
}

pkg/admission/certprovisioner/doc.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
Copyright 2018 The Kubernetes Authors.
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+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
/*
18+
Package certprovisioner provides an interface and implementation to provision certificates.
19+
20+
Create a implementation instance of certprovisioner.
21+
22+
cp := SelfSignedCertProvisioner{
23+
CommonName: "foo.bar.com"
24+
}
25+
26+
Provision the certificates.
27+
certs, err := cp.ProvisionServingCert()
28+
if err != nil {
29+
// handle error
30+
}
31+
*/
32+
package certprovisioner
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/*
2+
Copyright 2018 The Kubernetes Authors.
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+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package certprovisioner
18+
19+
import (
20+
"crypto/x509"
21+
"fmt"
22+
23+
"k8s.io/client-go/util/cert"
24+
)
25+
26+
// ServiceToCommonName generates the CommonName for the certificate when using a k8s service.
27+
func ServiceToCommonName(serviceNamespace, serviceName string) string {
28+
return fmt.Sprintf("%s.%s.svc", serviceName, serviceNamespace)
29+
}
30+
31+
// SelfSignedCertProvisioner implements the CertProvisioner interface.
32+
// It provisions self-signed certificates.
33+
type SelfSignedCertProvisioner struct {
34+
// Required Common Name
35+
CommonName string
36+
}
37+
38+
var _ CertProvisioner = &SelfSignedCertProvisioner{}
39+
40+
// ProvisionServingCert creates and returns a CA certificate, certificate and
41+
// key for the server. serverKey and serverCert are used by the server
42+
// to establish trust for clients, CA certificate is used by the
43+
// client to verify the server authentication chain.
44+
// The cert will be valid for 365 days.
45+
func (cp *SelfSignedCertProvisioner) ProvisionServingCert() (*Certs, error) {
46+
signingKey, err := cert.NewPrivateKey()
47+
if err != nil {
48+
return nil, fmt.Errorf("failed to create the CA private key: %v", err)
49+
}
50+
signingCert, err := cert.NewSelfSignedCACert(cert.Config{CommonName: "webhook-cert-ca"}, signingKey)
51+
if err != nil {
52+
return nil, fmt.Errorf("failed to create the CA cert: %v", err)
53+
}
54+
key, err := cert.NewPrivateKey()
55+
if err != nil {
56+
return nil, fmt.Errorf("failed to create the private key: %v", err)
57+
}
58+
signedCert, err := cert.NewSignedCert(
59+
cert.Config{
60+
CommonName: cp.CommonName,
61+
Usages: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
62+
},
63+
key, signingCert, signingKey,
64+
)
65+
if err != nil {
66+
return nil, fmt.Errorf("failed to create the cert: %v", err)
67+
}
68+
return &Certs{
69+
Key: cert.EncodePrivateKeyPEM(key),
70+
Cert: cert.EncodeCertPEM(signedCert),
71+
CACert: cert.EncodeCertPEM(signingCert),
72+
}, nil
73+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/*
2+
Copyright 2018 The Kubernetes Authors.
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+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package certprovisioner
18+
19+
import (
20+
"crypto/x509"
21+
"encoding/pem"
22+
"testing"
23+
)
24+
25+
func TestProvisionServingCert(t *testing.T) {
26+
cn := "mysvc.myns.svc"
27+
cp := SelfSignedCertProvisioner{CommonName: cn}
28+
certs, err := cp.ProvisionServingCert()
29+
30+
// First, create the set of root certificates. For this example we only
31+
// have one. It's also possible to omit this in order to use the
32+
// default root set of the current operating system.
33+
roots := x509.NewCertPool()
34+
ok := roots.AppendCertsFromPEM(certs.CACert)
35+
if !ok {
36+
t.Fatalf("failed to parse root certificate: %s", certs.CACert)
37+
}
38+
39+
block, _ := pem.Decode(certs.Cert)
40+
if block == nil {
41+
t.Fatalf("failed to parse certificate PEM: %s", certs.Cert)
42+
}
43+
cert, err := x509.ParseCertificate(block.Bytes)
44+
if err != nil {
45+
t.Fatalf("failed to parse certificate: %v", err)
46+
}
47+
48+
opts := x509.VerifyOptions{
49+
DNSName: cn,
50+
Roots: roots,
51+
}
52+
53+
if _, err := cert.Verify(opts); err != nil {
54+
t.Fatalf("failed to verify certificate: %v", err)
55+
}
56+
}

0 commit comments

Comments
 (0)