...

Source file src/github.com/sigstore/cosign/v2/test/cert_utils.go

Documentation: github.com/sigstore/cosign/v2/test

     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 test
    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(-5 * time.Hour),
    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(-2 * 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 GenerateLeafCertWithExpiration(subject string, oidcIssuer string, expiration time.Time,
   121  	priv *ecdsa.PrivateKey,
   122  	parentTemplate *x509.Certificate, parentPriv crypto.Signer) (*x509.Certificate, error) {
   123  	certTemplate := &x509.Certificate{
   124  		SerialNumber:   big.NewInt(1),
   125  		EmailAddresses: []string{subject},
   126  		NotBefore:      expiration,
   127  		NotAfter:       expiration.Add(10 * time.Minute),
   128  		KeyUsage:       x509.KeyUsageDigitalSignature,
   129  		ExtKeyUsage:    []x509.ExtKeyUsage{x509.ExtKeyUsageCodeSigning},
   130  		IsCA:           false,
   131  		ExtraExtensions: []pkix.Extension{{
   132  			// OID for OIDC Issuer extension
   133  			Id:       asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 57264, 1, 1},
   134  			Critical: false,
   135  			Value:    []byte(oidcIssuer),
   136  		},
   137  		},
   138  	}
   139  
   140  	cert, err := createCertificate(certTemplate, parentTemplate, &priv.PublicKey, parentPriv)
   141  	if err != nil {
   142  		return nil, err
   143  	}
   144  
   145  	return cert, nil
   146  }
   147  
   148  func GenerateLeafCert(subject string, oidcIssuer string, parentTemplate *x509.Certificate, parentPriv crypto.Signer, exts ...pkix.Extension) (*x509.Certificate, *ecdsa.PrivateKey, error) {
   149  	exts = append(exts, pkix.Extension{
   150  		// OID for OIDC Issuer extension
   151  		Id:       asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 57264, 1, 1},
   152  		Critical: false,
   153  		Value:    []byte(oidcIssuer),
   154  	})
   155  	certTemplate := &x509.Certificate{
   156  		SerialNumber:    big.NewInt(1),
   157  		EmailAddresses:  []string{subject},
   158  		NotBefore:       time.Now().Add(-1 * time.Minute),
   159  		NotAfter:        time.Now().Add(time.Hour),
   160  		KeyUsage:        x509.KeyUsageDigitalSignature,
   161  		ExtKeyUsage:     []x509.ExtKeyUsage{x509.ExtKeyUsageCodeSigning},
   162  		IsCA:            false,
   163  		ExtraExtensions: exts,
   164  	}
   165  
   166  	priv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
   167  	if err != nil {
   168  		return nil, nil, err
   169  	}
   170  
   171  	cert, err := createCertificate(certTemplate, parentTemplate, &priv.PublicKey, parentPriv)
   172  	if err != nil {
   173  		return nil, nil, err
   174  	}
   175  
   176  	return cert, priv, nil
   177  }
   178  
   179  func GenerateLeafCertWithGitHubOIDs(subject string, oidcIssuer string, githubWorkflowTrigger, githubWorkflowSha, githubWorkflowName,
   180  	githubWorkflowRepository, githubWorkflowRef string, parentTemplate *x509.Certificate, parentPriv crypto.Signer) (*x509.Certificate, *ecdsa.PrivateKey, error) {
   181  	certTemplate := &x509.Certificate{
   182  		SerialNumber:   big.NewInt(1),
   183  		EmailAddresses: []string{subject},
   184  		NotBefore:      time.Now().Add(-1 * time.Minute),
   185  		NotAfter:       time.Now().Add(time.Hour),
   186  		KeyUsage:       x509.KeyUsageDigitalSignature,
   187  		ExtKeyUsage:    []x509.ExtKeyUsage{x509.ExtKeyUsageCodeSigning},
   188  		IsCA:           false,
   189  		ExtraExtensions: []pkix.Extension{{
   190  			// OID for OIDC Issuer extension
   191  			Id:       asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 57264, 1, 1},
   192  			Critical: false,
   193  			Value:    []byte(oidcIssuer),
   194  		},
   195  			{Id: asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 57264, 1, 2}, Value: []byte(githubWorkflowTrigger)},
   196  			{Id: asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 57264, 1, 3}, Value: []byte(githubWorkflowSha)},
   197  			{Id: asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 57264, 1, 4}, Value: []byte(githubWorkflowName)},
   198  			{Id: asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 57264, 1, 5}, Value: []byte(githubWorkflowRepository)},
   199  			{Id: asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 57264, 1, 6}, Value: []byte(githubWorkflowRef)}},
   200  	}
   201  
   202  	priv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
   203  	if err != nil {
   204  		return nil, nil, err
   205  	}
   206  
   207  	cert, err := createCertificate(certTemplate, parentTemplate, &priv.PublicKey, parentPriv)
   208  	if err != nil {
   209  		return nil, nil, err
   210  	}
   211  
   212  	return cert, priv, nil
   213  }
   214  
   215  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) {
   216  	certTemplate := &x509.Certificate{
   217  		SerialNumber:   big.NewInt(1),
   218  		EmailAddresses: emailAddresses,
   219  		DNSNames:       dnsNames,
   220  		IPAddresses:    ipAddresses,
   221  		URIs:           uris,
   222  		NotBefore:      time.Now().Add(-1 * time.Minute),
   223  		NotAfter:       time.Now().Add(time.Hour),
   224  		KeyUsage:       x509.KeyUsageDigitalSignature,
   225  		ExtKeyUsage:    []x509.ExtKeyUsage{x509.ExtKeyUsageCodeSigning},
   226  		IsCA:           false,
   227  		ExtraExtensions: []pkix.Extension{{
   228  			// OID for OIDC Issuer extension
   229  			Id:       asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 57264, 1, 1},
   230  			Critical: false,
   231  			Value:    []byte(oidcIssuer),
   232  		}},
   233  	}
   234  
   235  	priv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
   236  	if err != nil {
   237  		return nil, nil, err
   238  	}
   239  
   240  	cert, err := createCertificate(certTemplate, parentTemplate, &priv.PublicKey, parentPriv)
   241  	if err != nil {
   242  		return nil, nil, err
   243  	}
   244  
   245  	return cert, priv, nil
   246  }
   247  

View as plain text