k8s.io/client-go@v0.31.1/util/certificate/csr/csr_test.go (about)

     1  /*
     2  Copyright 2020 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 csr
    18  
    19  import (
    20  	"crypto"
    21  	"crypto/rand"
    22  	"crypto/rsa"
    23  	"crypto/x509"
    24  	"crypto/x509/pkix"
    25  	"encoding/pem"
    26  	"testing"
    27  
    28  	certificates "k8s.io/api/certificates/v1"
    29  )
    30  
    31  func TestEnsureCompatible(t *testing.T) {
    32  	privateKey, err := rsa.GenerateKey(rand.Reader, 2048)
    33  	if err != nil {
    34  		t.Fatal(err)
    35  	}
    36  	req := pemWithPrivateKey(privateKey)
    37  
    38  	tests := map[string]struct {
    39  		new, orig  *certificates.CertificateSigningRequest
    40  		privateKey interface{}
    41  		err        string
    42  	}{
    43  		"nil signerName on 'new' matches any signerName on 'orig'": {
    44  			new: &certificates.CertificateSigningRequest{
    45  				Spec: certificates.CertificateSigningRequestSpec{
    46  					Request: req,
    47  				},
    48  			},
    49  			orig: &certificates.CertificateSigningRequest{
    50  				Spec: certificates.CertificateSigningRequestSpec{
    51  					Request:    req,
    52  					SignerName: "example.com/test",
    53  				},
    54  			},
    55  			privateKey: privateKey,
    56  		},
    57  		"nil signerName on 'orig' matches any signerName on 'new'": {
    58  			new: &certificates.CertificateSigningRequest{
    59  				Spec: certificates.CertificateSigningRequestSpec{
    60  					Request:    req,
    61  					SignerName: "example.com/test",
    62  				},
    63  			},
    64  			orig: &certificates.CertificateSigningRequest{
    65  				Spec: certificates.CertificateSigningRequestSpec{
    66  					Request: req,
    67  				},
    68  			},
    69  			privateKey: privateKey,
    70  		},
    71  		"signerName on 'orig' matches signerName on 'new'": {
    72  			new: &certificates.CertificateSigningRequest{
    73  				Spec: certificates.CertificateSigningRequestSpec{
    74  					Request:    req,
    75  					SignerName: "example.com/test",
    76  				},
    77  			},
    78  			orig: &certificates.CertificateSigningRequest{
    79  				Spec: certificates.CertificateSigningRequestSpec{
    80  					Request:    req,
    81  					SignerName: "example.com/test",
    82  				},
    83  			},
    84  			privateKey: privateKey,
    85  		},
    86  		"signerName on 'orig' does not match signerName on 'new'": {
    87  			new: &certificates.CertificateSigningRequest{
    88  				Spec: certificates.CertificateSigningRequestSpec{
    89  					Request:    req,
    90  					SignerName: "example.com/test",
    91  				},
    92  			},
    93  			orig: &certificates.CertificateSigningRequest{
    94  				Spec: certificates.CertificateSigningRequestSpec{
    95  					Request:    req,
    96  					SignerName: "example.com/not-test",
    97  				},
    98  			},
    99  			privateKey: privateKey,
   100  			err:        `csr signerNames differ: new "example.com/test", orig: "example.com/not-test"`,
   101  		},
   102  	}
   103  	for name, test := range tests {
   104  		t.Run(name, func(t *testing.T) {
   105  			err := ensureCompatible(test.new, test.orig, test.privateKey)
   106  			if err != nil && test.err == "" {
   107  				t.Errorf("expected no error, but got: %v", err)
   108  			} else if err != nil && test.err != err.Error() {
   109  				t.Errorf("error did not match as expected, got=%v, exp=%s", err, test.err)
   110  			}
   111  			if err == nil && test.err != "" {
   112  				t.Errorf("expected to get an error but got none")
   113  			}
   114  		})
   115  	}
   116  }
   117  
   118  func pemWithPrivateKey(pk crypto.PrivateKey) []byte {
   119  	template := &x509.CertificateRequest{
   120  		Subject: pkix.Name{
   121  			CommonName:   "something",
   122  			Organization: []string{"test"},
   123  		},
   124  	}
   125  	return pemWithTemplate(template, pk)
   126  }
   127  
   128  func pemWithTemplate(template *x509.CertificateRequest, key crypto.PrivateKey) []byte {
   129  	csrDER, err := x509.CreateCertificateRequest(rand.Reader, template, key)
   130  	if err != nil {
   131  		panic(err)
   132  	}
   133  
   134  	csrPemBlock := &pem.Block{
   135  		Type:  "CERTIFICATE REQUEST",
   136  		Bytes: csrDER,
   137  	}
   138  
   139  	p := pem.EncodeToMemory(csrPemBlock)
   140  	if p == nil {
   141  		panic("invalid pem block")
   142  	}
   143  
   144  	return p
   145  }