istio.io/istio@v0.0.0-20240520182934-d79c90f27776/tests/fuzz/security_fuzzer.go (about)

     1  // Copyright Istio 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 fuzz
    16  
    17  import (
    18  	"context"
    19  	"crypto/tls"
    20  	"crypto/x509"
    21  	"crypto/x509/pkix"
    22  	"net"
    23  
    24  	fuzz "github.com/AdaLogics/go-fuzz-headers"
    25  	"google.golang.org/grpc/credentials"
    26  	"google.golang.org/grpc/peer"
    27  
    28  	pb "istio.io/api/security/v1alpha1"
    29  	"istio.io/istio/pkg/security"
    30  	mockca "istio.io/istio/security/pkg/pki/ca/mock"
    31  	"istio.io/istio/security/pkg/pki/util"
    32  	"istio.io/istio/security/pkg/server/ca"
    33  	"istio.io/istio/security/pkg/server/ca/authenticate"
    34  )
    35  
    36  func FuzzGenCSR(data []byte) int {
    37  	f := fuzz.NewConsumer(data)
    38  	certOptions := util.CertOptions{}
    39  	err := f.GenerateStruct(&certOptions)
    40  	if err != nil {
    41  		return 0
    42  	}
    43  	_, _, _ = util.GenCSR(certOptions)
    44  	return 1
    45  }
    46  
    47  func fuzzedCertChain(f *fuzz.ConsumeFuzzer) ([][]*x509.Certificate, error) {
    48  	certChain := [][]*x509.Certificate{}
    49  	withPkixExtension, err := f.GetBool()
    50  	if err != nil {
    51  		return certChain, err
    52  	}
    53  	if withPkixExtension {
    54  		ids := []util.Identity{}
    55  		err := f.GenerateStruct(&ids)
    56  		if err != nil {
    57  			return certChain, err
    58  		}
    59  		sanExt, err := util.BuildSANExtension(ids)
    60  		if err != nil {
    61  			return certChain, err
    62  		}
    63  		certChain = [][]*x509.Certificate{
    64  			{
    65  				{
    66  					Extensions: []pkix.Extension{*sanExt},
    67  				},
    68  			},
    69  		}
    70  	}
    71  	return certChain, nil
    72  }
    73  
    74  func FuzzCreateCertE2EUsingClientCertAuthenticator(data []byte) int {
    75  	f := fuzz.NewConsumer(data)
    76  	certChainBytes, err := f.GetBytes()
    77  	if err != nil {
    78  		return 0
    79  	}
    80  	// Check that certChainBytes can be parsed successfully
    81  	_, err = util.ParsePemEncodedCertificate(certChainBytes)
    82  	if err != nil {
    83  		return 0
    84  	}
    85  	rootCertBytes, err := f.GetBytes()
    86  	if err != nil {
    87  		return 0
    88  	}
    89  	// Check that rootCertBytes can be parsed successfully
    90  	_, err = util.ParsePemEncodedCertificate(rootCertBytes)
    91  	if err != nil {
    92  		return 0
    93  	}
    94  	signedCert, err := f.GetBytes()
    95  	if err != nil {
    96  		return 0
    97  	}
    98  
    99  	auth := &authenticate.ClientCertAuthenticator{}
   100  	kcb := util.NewKeyCertBundleFromPem(nil, nil, certChainBytes, rootCertBytes)
   101  
   102  	mockCa := &mockca.FakeCA{
   103  		SignedCert:    signedCert,
   104  		KeyCertBundle: kcb,
   105  	}
   106  	server, err := ca.New(mockCa, 1, []security.Authenticator{auth}, nil)
   107  	if err != nil {
   108  		return 0
   109  	}
   110  	csrString, err := f.GetString()
   111  	if err != nil {
   112  		return 0
   113  	}
   114  	request := &pb.IstioCertificateRequest{Csr: csrString}
   115  	ctx := context.Background()
   116  
   117  	certChain, err := fuzzedCertChain(f)
   118  	if err != nil {
   119  		return 0
   120  	}
   121  	tlsInfo := credentials.TLSInfo{
   122  		State: tls.ConnectionState{VerifiedChains: certChain},
   123  	}
   124  
   125  	mockIPAddr := &net.IPAddr{IP: net.IPv4(192, 168, 1, 1)}
   126  	p := &peer.Peer{Addr: mockIPAddr, AuthInfo: tlsInfo}
   127  
   128  	ctx = peer.NewContext(ctx, p)
   129  
   130  	_, _ = server.CreateCertificate(ctx, request)
   131  	return 1
   132  }