...

Source file src/github.com/sigstore/rekor/pkg/pki/x509/testutils/cert_test_utils.go

Documentation: github.com/sigstore/rekor/pkg/pki/x509/testutils

     1  // Copyright 2022 The Sigstore 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 testutils
    16  
    17  import (
    18  	"crypto"
    19  	"crypto/ecdsa"
    20  	"crypto/elliptic"
    21  	"crypto/rand"
    22  	"crypto/x509"
    23  	"crypto/x509/pkix"
    24  	"encoding/asn1"
    25  	"math/big"
    26  	"net"
    27  	"net/url"
    28  	"time"
    29  )
    30  
    31  /*
    32  To use:
    33  
    34  rootCert, rootKey, _ := GenerateRootCa()
    35  subCert, subKey, _ := GenerateSubordinateCa(rootCert, rootKey)
    36  leafCert, _, _ := GenerateLeafCert("subject", "oidc-issuer", subCert, subKey)
    37  
    38  roots := x509.NewCertPool()
    39  subs := x509.NewCertPool()
    40  roots.AddCert(rootCert)
    41  subs.AddCert(subCert)
    42  opts := x509.VerifyOptions{
    43  	Roots:         roots,
    44  	Intermediates: subs,
    45  	KeyUsages: []x509.ExtKeyUsage{
    46  		x509.ExtKeyUsageCodeSigning,
    47  	},
    48  }
    49  _, err := leafCert.Verify(opts)
    50  */
    51  
    52  func createCertificate(template *x509.Certificate, parent *x509.Certificate, pub interface{}, priv crypto.Signer) (*x509.Certificate, error) {
    53  	certBytes, err := x509.CreateCertificate(rand.Reader, template, parent, pub, priv)
    54  	if err != nil {
    55  		return nil, err
    56  	}
    57  
    58  	cert, err := x509.ParseCertificate(certBytes)
    59  	if err != nil {
    60  		return nil, err
    61  	}
    62  	return cert, nil
    63  }
    64  
    65  func GenerateRootCa() (*x509.Certificate, *ecdsa.PrivateKey, error) {
    66  	rootTemplate := &x509.Certificate{
    67  		SerialNumber: big.NewInt(1),
    68  		Subject: pkix.Name{
    69  			CommonName:   "sigstore",
    70  			Organization: []string{"sigstore.dev"},
    71  		},
    72  		NotBefore:             time.Now().Add(-10 * time.Minute),
    73  		NotAfter:              time.Now().Add(5 * time.Hour),
    74  		KeyUsage:              x509.KeyUsageCertSign | x509.KeyUsageCRLSign,
    75  		BasicConstraintsValid: true,
    76  		IsCA:                  true,
    77  	}
    78  
    79  	priv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
    80  	if err != nil {
    81  		return nil, nil, err
    82  	}
    83  
    84  	cert, err := createCertificate(rootTemplate, rootTemplate, &priv.PublicKey, priv)
    85  	if err != nil {
    86  		return nil, nil, err
    87  	}
    88  
    89  	return cert, priv, nil
    90  }
    91  
    92  func GenerateSubordinateCa(rootTemplate *x509.Certificate, rootPriv crypto.Signer) (*x509.Certificate, *ecdsa.PrivateKey, error) {
    93  	subTemplate := &x509.Certificate{
    94  		SerialNumber: big.NewInt(1),
    95  		Subject: pkix.Name{
    96  			CommonName:   "sigstore-sub",
    97  			Organization: []string{"sigstore.dev"},
    98  		},
    99  		NotBefore:             time.Now().Add(-9 * time.Minute),
   100  		NotAfter:              time.Now().Add(2 * time.Hour),
   101  		KeyUsage:              x509.KeyUsageCertSign | x509.KeyUsageCRLSign,
   102  		ExtKeyUsage:           []x509.ExtKeyUsage{x509.ExtKeyUsageCodeSigning},
   103  		BasicConstraintsValid: true,
   104  		IsCA:                  true,
   105  	}
   106  
   107  	priv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
   108  	if err != nil {
   109  		return nil, nil, err
   110  	}
   111  
   112  	cert, err := createCertificate(subTemplate, rootTemplate, &priv.PublicKey, rootPriv)
   113  	if err != nil {
   114  		return nil, nil, err
   115  	}
   116  
   117  	return cert, priv, nil
   118  }
   119  
   120  func GenerateLeafCert(subject, oidcIssuer string, uri *url.URL, parentTemplate *x509.Certificate, parentPriv crypto.Signer, exts ...pkix.Extension) (*x509.Certificate, *ecdsa.PrivateKey, error) {
   121  	exts = append(exts, pkix.Extension{
   122  		// OID for OIDC Issuer extension
   123  		Id:       asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 57264, 1, 1},
   124  		Critical: false,
   125  		Value:    []byte(oidcIssuer),
   126  	})
   127  	certTemplate := &x509.Certificate{
   128  		SerialNumber:    big.NewInt(1),
   129  		EmailAddresses:  []string{subject},
   130  		NotBefore:       time.Now().Add(-1 * time.Minute),
   131  		NotAfter:        time.Now().Add(time.Hour),
   132  		KeyUsage:        x509.KeyUsageDigitalSignature,
   133  		ExtKeyUsage:     []x509.ExtKeyUsage{x509.ExtKeyUsageCodeSigning},
   134  		IsCA:            false,
   135  		ExtraExtensions: exts,
   136  	}
   137  	if uri != nil {
   138  		certTemplate.URIs = []*url.URL{uri}
   139  	}
   140  
   141  	priv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
   142  	if err != nil {
   143  		return nil, nil, err
   144  	}
   145  
   146  	cert, err := createCertificate(certTemplate, parentTemplate, &priv.PublicKey, parentPriv)
   147  	if err != nil {
   148  		return nil, nil, err
   149  	}
   150  
   151  	return cert, priv, nil
   152  }
   153  
   154  func GenerateExpiredLeafCert(subject string, oidcIssuer string, parentTemplate *x509.Certificate, parentPriv crypto.Signer) (*x509.Certificate, *ecdsa.PrivateKey, error) {
   155  	certTemplate := &x509.Certificate{
   156  		SerialNumber:   big.NewInt(1),
   157  		EmailAddresses: []string{subject},
   158  		NotBefore:      time.Now().Add(-5 * time.Minute),
   159  		NotAfter:       time.Now().Add(-2 * time.Minute),
   160  		KeyUsage:       x509.KeyUsageDigitalSignature,
   161  		ExtKeyUsage:    []x509.ExtKeyUsage{x509.ExtKeyUsageCodeSigning},
   162  		IsCA:           false,
   163  		ExtraExtensions: []pkix.Extension{{
   164  			// OID for OIDC Issuer extension
   165  			Id:       asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 57264, 1, 1},
   166  			Critical: false,
   167  			Value:    []byte(oidcIssuer),
   168  		}},
   169  	}
   170  
   171  	priv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
   172  	if err != nil {
   173  		return nil, nil, err
   174  	}
   175  
   176  	cert, err := createCertificate(certTemplate, parentTemplate, &priv.PublicKey, parentPriv)
   177  	if err != nil {
   178  		return nil, nil, err
   179  	}
   180  
   181  	return cert, priv, nil
   182  }
   183  
   184  func GenerateLeafCertWithSubjectAlternateNames(dnsNames []string, emailAddresses []string, ipAddresses []net.IP, uris []*url.URL, oidcIssuer string, parentTemplate *x509.Certificate, parentPriv crypto.Signer) (*x509.Certificate, *ecdsa.PrivateKey, error) {
   185  	certTemplate := &x509.Certificate{
   186  		SerialNumber:   big.NewInt(1),
   187  		EmailAddresses: emailAddresses,
   188  		DNSNames:       dnsNames,
   189  		IPAddresses:    ipAddresses,
   190  		URIs:           uris,
   191  		NotBefore:      time.Now().Add(-1 * time.Minute),
   192  		NotAfter:       time.Now().Add(time.Hour),
   193  		KeyUsage:       x509.KeyUsageDigitalSignature,
   194  		ExtKeyUsage:    []x509.ExtKeyUsage{x509.ExtKeyUsageCodeSigning},
   195  		IsCA:           false,
   196  		ExtraExtensions: []pkix.Extension{{
   197  			// OID for OIDC Issuer extension
   198  			Id:       asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 57264, 1, 1},
   199  			Critical: false,
   200  			Value:    []byte(oidcIssuer),
   201  		}},
   202  	}
   203  
   204  	priv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
   205  	if err != nil {
   206  		return nil, nil, err
   207  	}
   208  
   209  	cert, err := createCertificate(certTemplate, parentTemplate, &priv.PublicKey, parentPriv)
   210  	if err != nil {
   211  		return nil, nil, err
   212  	}
   213  
   214  	return cert, priv, nil
   215  }
   216  

View as plain text