...

Source file src/github.com/letsencrypt/boulder/cmd/ceremony/main_test.go

Documentation: github.com/letsencrypt/boulder/cmd/ceremony

     1  package main
     2  
     3  import (
     4  	"fmt"
     5  	"io/fs"
     6  	"strings"
     7  	"testing"
     8  
     9  	"github.com/letsencrypt/boulder/test"
    10  )
    11  
    12  func TestLoadPubKey(t *testing.T) {
    13  	_, _, err := loadPubKey("../../test/test-root.pubkey.pem")
    14  	test.AssertNotError(t, err, "should not have errored")
    15  
    16  	_, _, err = loadPubKey("../../test/hierarchy/int-e1.key.pem")
    17  	test.AssertError(t, err, "should have failed trying to parse a private key")
    18  
    19  	_, _, err = loadPubKey("/path/that/will/not/ever/exist/ever")
    20  	test.AssertError(t, err, "should have failed opening public key at non-existent path")
    21  	test.AssertErrorIs(t, err, fs.ErrNotExist)
    22  
    23  	_, _, err = loadPubKey("../../test/hierarchy/int-e1.cert.pem")
    24  	test.AssertError(t, err, "should have failed when trying to parse a certificate")
    25  }
    26  
    27  func TestCheckOutputFileSucceeds(t *testing.T) {
    28  	dir := t.TempDir()
    29  	err := checkOutputFile(dir+"/example", "foo")
    30  	if err != nil {
    31  		t.Fatal(err)
    32  	}
    33  }
    34  
    35  func TestCheckOutputFileEmpty(t *testing.T) {
    36  	err := checkOutputFile("", "foo")
    37  	if err == nil {
    38  		t.Fatal("expected error, got none")
    39  	}
    40  	if err.Error() != "outputs.foo is required" {
    41  		t.Fatalf("wrong error: %s", err)
    42  	}
    43  }
    44  
    45  func TestCheckOutputFileExists(t *testing.T) {
    46  	dir := t.TempDir()
    47  	filename := dir + "/example"
    48  	err := writeFile(filename, []byte("hi"))
    49  	if err != nil {
    50  		t.Fatal(err)
    51  	}
    52  	err = checkOutputFile(filename, "foo")
    53  	if err == nil {
    54  		t.Fatal("expected error, got none")
    55  	}
    56  	if !strings.Contains(err.Error(), "already exists") {
    57  		t.Fatalf("wrong error: %s", err)
    58  	}
    59  }
    60  
    61  func TestKeyGenConfigValidate(t *testing.T) {
    62  	cases := []struct {
    63  		name          string
    64  		config        keyGenConfig
    65  		expectedError string
    66  	}{
    67  		{
    68  			name:          "no key.type",
    69  			config:        keyGenConfig{},
    70  			expectedError: "key.type is required",
    71  		},
    72  		{
    73  			name: "bad key.type",
    74  			config: keyGenConfig{
    75  				Type: "doop",
    76  			},
    77  			expectedError: "key.type can only be 'rsa' or 'ecdsa'",
    78  		},
    79  		{
    80  			name: "bad key.rsa-mod-length",
    81  			config: keyGenConfig{
    82  				Type:         "rsa",
    83  				RSAModLength: 1337,
    84  			},
    85  			expectedError: "key.rsa-mod-length can only be 2048 or 4096",
    86  		},
    87  		{
    88  			name: "key.type is rsa but key.ecdsa-curve is present",
    89  			config: keyGenConfig{
    90  				Type:         "rsa",
    91  				RSAModLength: 2048,
    92  				ECDSACurve:   "bad",
    93  			},
    94  			expectedError: "if key.type = 'rsa' then key.ecdsa-curve is not used",
    95  		},
    96  		{
    97  			name: "bad key.ecdsa-curve",
    98  			config: keyGenConfig{
    99  				Type:       "ecdsa",
   100  				ECDSACurve: "bad",
   101  			},
   102  			expectedError: "key.ecdsa-curve can only be 'P-224', 'P-256', 'P-384', or 'P-521'",
   103  		},
   104  		{
   105  			name: "key.type is ecdsa but key.rsa-mod-length is present",
   106  			config: keyGenConfig{
   107  				Type:         "ecdsa",
   108  				RSAModLength: 2048,
   109  				ECDSACurve:   "P-256",
   110  			},
   111  			expectedError: "if key.type = 'ecdsa' then key.rsa-mod-length is not used",
   112  		},
   113  		{
   114  			name: "good rsa config",
   115  			config: keyGenConfig{
   116  				Type:         "rsa",
   117  				RSAModLength: 2048,
   118  			},
   119  		},
   120  		{
   121  			name: "good ecdsa config",
   122  			config: keyGenConfig{
   123  				Type:       "ecdsa",
   124  				ECDSACurve: "P-256",
   125  			},
   126  		},
   127  	}
   128  	for _, tc := range cases {
   129  		t.Run(tc.name, func(t *testing.T) {
   130  			err := tc.config.validate()
   131  			if err != nil && err.Error() != tc.expectedError {
   132  				t.Fatalf("Unexpected error, wanted: %q, got: %q", tc.expectedError, err)
   133  			} else if err == nil && tc.expectedError != "" {
   134  				t.Fatalf("validate didn't fail, wanted: %q", err)
   135  			}
   136  		})
   137  	}
   138  }
   139  
   140  func TestRootConfigValidate(t *testing.T) {
   141  	cases := []struct {
   142  		name          string
   143  		config        rootConfig
   144  		expectedError string
   145  	}{
   146  		{
   147  			name:          "no pkcs11.module",
   148  			config:        rootConfig{},
   149  			expectedError: "pkcs11.module is required",
   150  		},
   151  		{
   152  			name: "no pkcs11.store-key-with-label",
   153  			config: rootConfig{
   154  				PKCS11: PKCS11KeyGenConfig{
   155  					Module: "module",
   156  				},
   157  			},
   158  			expectedError: "pkcs11.store-key-with-label is required",
   159  		},
   160  		{
   161  			name: "bad key fields",
   162  			config: rootConfig{
   163  				PKCS11: PKCS11KeyGenConfig{
   164  					Module:     "module",
   165  					StoreLabel: "label",
   166  				},
   167  			},
   168  			expectedError: "key.type is required",
   169  		},
   170  		{
   171  			name: "no outputs.public-key-path",
   172  			config: rootConfig{
   173  				PKCS11: PKCS11KeyGenConfig{
   174  					Module:     "module",
   175  					StoreLabel: "label",
   176  				},
   177  				Key: keyGenConfig{
   178  					Type:         "rsa",
   179  					RSAModLength: 2048,
   180  				},
   181  			},
   182  			expectedError: "outputs.public-key-path is required",
   183  		},
   184  		{
   185  			name: "no outputs.certificate-path",
   186  			config: rootConfig{
   187  				PKCS11: PKCS11KeyGenConfig{
   188  					Module:     "module",
   189  					StoreLabel: "label",
   190  				},
   191  				Key: keyGenConfig{
   192  					Type:         "rsa",
   193  					RSAModLength: 2048,
   194  				},
   195  				Outputs: struct {
   196  					PublicKeyPath   string `yaml:"public-key-path"`
   197  					CertificatePath string `yaml:"certificate-path"`
   198  				}{
   199  					PublicKeyPath: "path",
   200  				},
   201  			},
   202  			expectedError: "outputs.certificate-path is required",
   203  		},
   204  		{
   205  			name: "bad certificate-profile",
   206  			config: rootConfig{
   207  				PKCS11: PKCS11KeyGenConfig{
   208  					Module:     "module",
   209  					StoreLabel: "label",
   210  				},
   211  				Key: keyGenConfig{
   212  					Type:         "rsa",
   213  					RSAModLength: 2048,
   214  				},
   215  				Outputs: struct {
   216  					PublicKeyPath   string `yaml:"public-key-path"`
   217  					CertificatePath string `yaml:"certificate-path"`
   218  				}{
   219  					PublicKeyPath:   "path",
   220  					CertificatePath: "path",
   221  				},
   222  			},
   223  			expectedError: "not-before is required",
   224  		},
   225  		{
   226  			name: "good config",
   227  			config: rootConfig{
   228  				PKCS11: PKCS11KeyGenConfig{
   229  					Module:     "module",
   230  					StoreLabel: "label",
   231  				},
   232  				Key: keyGenConfig{
   233  					Type:         "rsa",
   234  					RSAModLength: 2048,
   235  				},
   236  				Outputs: struct {
   237  					PublicKeyPath   string `yaml:"public-key-path"`
   238  					CertificatePath string `yaml:"certificate-path"`
   239  				}{
   240  					PublicKeyPath:   "path",
   241  					CertificatePath: "path",
   242  				},
   243  				CertProfile: certProfile{
   244  					NotBefore:          "a",
   245  					NotAfter:           "b",
   246  					SignatureAlgorithm: "c",
   247  					CommonName:         "d",
   248  					Organization:       "e",
   249  					Country:            "f",
   250  				},
   251  				SkipLints: []string{
   252  					"e_ext_authority_key_identifier_missing",
   253  					"e_ext_authority_key_identifier_no_key_identifier",
   254  					"e_sub_ca_aia_missing",
   255  					"e_sub_ca_certificate_policies_missing",
   256  					"e_sub_ca_crl_distribution_points_missing",
   257  					"n_ca_digital_signature_not_set",
   258  					"n_mp_allowed_eku",
   259  					"n_sub_ca_eku_missing",
   260  					"w_sub_ca_aia_does_not_contain_issuing_ca_url",
   261  				},
   262  			},
   263  		},
   264  	}
   265  	for _, tc := range cases {
   266  		t.Run(tc.name, func(t *testing.T) {
   267  			err := tc.config.validate()
   268  			if err != nil && err.Error() != tc.expectedError {
   269  				t.Fatalf("Unexpected error, wanted: %q, got: %q", tc.expectedError, err)
   270  			} else if err == nil && tc.expectedError != "" {
   271  				t.Fatalf("validate didn't fail, wanted: %q", err)
   272  			}
   273  		})
   274  	}
   275  }
   276  
   277  func TestIntermediateConfigValidate(t *testing.T) {
   278  	cases := []struct {
   279  		name          string
   280  		config        intermediateConfig
   281  		expectedError string
   282  	}{
   283  		{
   284  			name:          "no pkcs11.module",
   285  			config:        intermediateConfig{},
   286  			expectedError: "pkcs11.module is required",
   287  		},
   288  		{
   289  			name: "no pkcs11.signing-key-label",
   290  			config: intermediateConfig{
   291  				PKCS11: PKCS11SigningConfig{
   292  					Module: "module",
   293  				},
   294  			},
   295  			expectedError: "pkcs11.signing-key-label is required",
   296  		},
   297  		{
   298  			name: "no inputs.public-key-path",
   299  			config: intermediateConfig{
   300  				PKCS11: PKCS11SigningConfig{
   301  					Module:       "module",
   302  					SigningLabel: "label",
   303  				},
   304  			},
   305  			expectedError: "inputs.public-key-path is required",
   306  		},
   307  		{
   308  			name: "no inputs.issuer-certificate-path",
   309  			config: intermediateConfig{
   310  				PKCS11: PKCS11SigningConfig{
   311  					Module:       "module",
   312  					SigningLabel: "label",
   313  				},
   314  				Inputs: struct {
   315  					PublicKeyPath         string `yaml:"public-key-path"`
   316  					IssuerCertificatePath string `yaml:"issuer-certificate-path"`
   317  				}{
   318  					PublicKeyPath: "path",
   319  				},
   320  			},
   321  			expectedError: "inputs.issuer-certificate is required",
   322  		},
   323  		{
   324  			name: "no outputs.certificate-path",
   325  			config: intermediateConfig{
   326  				PKCS11: PKCS11SigningConfig{
   327  					Module:       "module",
   328  					SigningLabel: "label",
   329  				},
   330  				Inputs: struct {
   331  					PublicKeyPath         string `yaml:"public-key-path"`
   332  					IssuerCertificatePath string `yaml:"issuer-certificate-path"`
   333  				}{
   334  					PublicKeyPath:         "path",
   335  					IssuerCertificatePath: "path",
   336  				},
   337  			},
   338  			expectedError: "outputs.certificate-path is required",
   339  		},
   340  		{
   341  			name: "bad certificate-profile",
   342  			config: intermediateConfig{
   343  				PKCS11: PKCS11SigningConfig{
   344  					Module:       "module",
   345  					SigningLabel: "label",
   346  				},
   347  				Inputs: struct {
   348  					PublicKeyPath         string `yaml:"public-key-path"`
   349  					IssuerCertificatePath string `yaml:"issuer-certificate-path"`
   350  				}{
   351  					PublicKeyPath:         "path",
   352  					IssuerCertificatePath: "path",
   353  				},
   354  				Outputs: struct {
   355  					CertificatePath string `yaml:"certificate-path"`
   356  				}{
   357  					CertificatePath: "path",
   358  				},
   359  			},
   360  			expectedError: "not-before is required",
   361  		},
   362  		{
   363  			name: "too many policy OIDs",
   364  			config: intermediateConfig{
   365  				PKCS11: PKCS11SigningConfig{
   366  					Module:       "module",
   367  					SigningLabel: "label",
   368  				},
   369  				Inputs: struct {
   370  					PublicKeyPath         string `yaml:"public-key-path"`
   371  					IssuerCertificatePath string `yaml:"issuer-certificate-path"`
   372  				}{
   373  					PublicKeyPath:         "path",
   374  					IssuerCertificatePath: "path",
   375  				},
   376  				Outputs: struct {
   377  					CertificatePath string `yaml:"certificate-path"`
   378  				}{
   379  					CertificatePath: "path",
   380  				},
   381  				CertProfile: certProfile{
   382  					NotBefore:          "a",
   383  					NotAfter:           "b",
   384  					SignatureAlgorithm: "c",
   385  					CommonName:         "d",
   386  					Organization:       "e",
   387  					Country:            "f",
   388  					OCSPURL:            "g",
   389  					CRLURL:             "h",
   390  					IssuerURL:          "i",
   391  					Policies:           []policyInfoConfig{{OID: "2.23.140.1.2.1"}, {OID: "6.6.6"}},
   392  				},
   393  				SkipLints: []string{},
   394  			},
   395  			expectedError: "policy should be exactly BRs domain-validated for subordinate CAs",
   396  		},
   397  		{
   398  			name: "too few policy OIDs",
   399  			config: intermediateConfig{
   400  				PKCS11: PKCS11SigningConfig{
   401  					Module:       "module",
   402  					SigningLabel: "label",
   403  				},
   404  				Inputs: struct {
   405  					PublicKeyPath         string `yaml:"public-key-path"`
   406  					IssuerCertificatePath string `yaml:"issuer-certificate-path"`
   407  				}{
   408  					PublicKeyPath:         "path",
   409  					IssuerCertificatePath: "path",
   410  				},
   411  				Outputs: struct {
   412  					CertificatePath string `yaml:"certificate-path"`
   413  				}{
   414  					CertificatePath: "path",
   415  				},
   416  				CertProfile: certProfile{
   417  					NotBefore:          "a",
   418  					NotAfter:           "b",
   419  					SignatureAlgorithm: "c",
   420  					CommonName:         "d",
   421  					Organization:       "e",
   422  					Country:            "f",
   423  					OCSPURL:            "g",
   424  					CRLURL:             "h",
   425  					IssuerURL:          "i",
   426  					Policies:           []policyInfoConfig{},
   427  				},
   428  				SkipLints: []string{},
   429  			},
   430  			expectedError: "policy should be exactly BRs domain-validated for subordinate CAs",
   431  		},
   432  		{
   433  			name: "good config",
   434  			config: intermediateConfig{
   435  				PKCS11: PKCS11SigningConfig{
   436  					Module:       "module",
   437  					SigningLabel: "label",
   438  				},
   439  				Inputs: struct {
   440  					PublicKeyPath         string `yaml:"public-key-path"`
   441  					IssuerCertificatePath string `yaml:"issuer-certificate-path"`
   442  				}{
   443  					PublicKeyPath:         "path",
   444  					IssuerCertificatePath: "path",
   445  				},
   446  				Outputs: struct {
   447  					CertificatePath string `yaml:"certificate-path"`
   448  				}{
   449  					CertificatePath: "path",
   450  				},
   451  				CertProfile: certProfile{
   452  					NotBefore:          "a",
   453  					NotAfter:           "b",
   454  					SignatureAlgorithm: "c",
   455  					CommonName:         "d",
   456  					Organization:       "e",
   457  					Country:            "f",
   458  					OCSPURL:            "g",
   459  					CRLURL:             "h",
   460  					IssuerURL:          "i",
   461  					Policies:           []policyInfoConfig{{OID: "2.23.140.1.2.1"}},
   462  				},
   463  				SkipLints: []string{},
   464  			},
   465  		},
   466  	}
   467  	for _, tc := range cases {
   468  		t.Run(tc.name, func(t *testing.T) {
   469  			err := tc.config.validate(intermediateCert)
   470  			if err != nil && err.Error() != tc.expectedError {
   471  				t.Fatalf("Unexpected error, wanted: %q, got: %q", tc.expectedError, err)
   472  			} else if err == nil && tc.expectedError != "" {
   473  				t.Fatalf("validate didn't fail, wanted: %q", err)
   474  			}
   475  		})
   476  	}
   477  }
   478  
   479  func TestCrossCertConfigValidate(t *testing.T) {
   480  	cases := []struct {
   481  		name          string
   482  		config        crossCertConfig
   483  		expectedError string
   484  	}{
   485  		{
   486  			name:          "no pkcs11.module",
   487  			config:        crossCertConfig{},
   488  			expectedError: "pkcs11.module is required",
   489  		},
   490  		{
   491  			name: "no pkcs11.signing-key-label",
   492  			config: crossCertConfig{
   493  				PKCS11: PKCS11SigningConfig{
   494  					Module: "module",
   495  				},
   496  			},
   497  			expectedError: "pkcs11.signing-key-label is required",
   498  		},
   499  		{
   500  			name: "no inputs.public-key-path",
   501  			config: crossCertConfig{
   502  				PKCS11: PKCS11SigningConfig{
   503  					Module:       "module",
   504  					SigningLabel: "label",
   505  				},
   506  			},
   507  			expectedError: "inputs.public-key-path is required",
   508  		},
   509  		{
   510  			name: "no inputs.issuer-certificate-path",
   511  			config: crossCertConfig{
   512  				PKCS11: PKCS11SigningConfig{
   513  					Module:       "module",
   514  					SigningLabel: "label",
   515  				},
   516  				Inputs: struct {
   517  					PublicKeyPath              string `yaml:"public-key-path"`
   518  					IssuerCertificatePath      string `yaml:"issuer-certificate-path"`
   519  					CertificateToCrossSignPath string `yaml:"certificate-to-cross-sign-path"`
   520  				}{
   521  					PublicKeyPath:              "path",
   522  					CertificateToCrossSignPath: "path",
   523  				},
   524  			},
   525  			expectedError: "inputs.issuer-certificate is required",
   526  		},
   527  		{
   528  			name: "no inputs.certificate-to-cross-sign-path",
   529  			config: crossCertConfig{
   530  				PKCS11: PKCS11SigningConfig{
   531  					Module:       "module",
   532  					SigningLabel: "label",
   533  				},
   534  				Inputs: struct {
   535  					PublicKeyPath              string `yaml:"public-key-path"`
   536  					IssuerCertificatePath      string `yaml:"issuer-certificate-path"`
   537  					CertificateToCrossSignPath string `yaml:"certificate-to-cross-sign-path"`
   538  				}{
   539  					PublicKeyPath:         "path",
   540  					IssuerCertificatePath: "path",
   541  				},
   542  			},
   543  			expectedError: "inputs.certificate-to-cross-sign-path is required",
   544  		},
   545  		{
   546  			name: "no outputs.certificate-path",
   547  			config: crossCertConfig{
   548  				PKCS11: PKCS11SigningConfig{
   549  					Module:       "module",
   550  					SigningLabel: "label",
   551  				},
   552  				Inputs: struct {
   553  					PublicKeyPath              string `yaml:"public-key-path"`
   554  					IssuerCertificatePath      string `yaml:"issuer-certificate-path"`
   555  					CertificateToCrossSignPath string `yaml:"certificate-to-cross-sign-path"`
   556  				}{
   557  					PublicKeyPath:              "path",
   558  					IssuerCertificatePath:      "path",
   559  					CertificateToCrossSignPath: "path",
   560  				},
   561  			},
   562  			expectedError: "outputs.certificate-path is required",
   563  		},
   564  		{
   565  			name: "bad certificate-profile",
   566  			config: crossCertConfig{
   567  				PKCS11: PKCS11SigningConfig{
   568  					Module:       "module",
   569  					SigningLabel: "label",
   570  				},
   571  				Inputs: struct {
   572  					PublicKeyPath              string `yaml:"public-key-path"`
   573  					IssuerCertificatePath      string `yaml:"issuer-certificate-path"`
   574  					CertificateToCrossSignPath string `yaml:"certificate-to-cross-sign-path"`
   575  				}{
   576  					PublicKeyPath:              "path",
   577  					IssuerCertificatePath:      "path",
   578  					CertificateToCrossSignPath: "path",
   579  				},
   580  				Outputs: struct {
   581  					CertificatePath string `yaml:"certificate-path"`
   582  				}{
   583  					CertificatePath: "path",
   584  				},
   585  			},
   586  			expectedError: "not-before is required",
   587  		},
   588  		{
   589  			name: "too many policy OIDs",
   590  			config: crossCertConfig{
   591  				PKCS11: PKCS11SigningConfig{
   592  					Module:       "module",
   593  					SigningLabel: "label",
   594  				},
   595  				Inputs: struct {
   596  					PublicKeyPath              string `yaml:"public-key-path"`
   597  					IssuerCertificatePath      string `yaml:"issuer-certificate-path"`
   598  					CertificateToCrossSignPath string `yaml:"certificate-to-cross-sign-path"`
   599  				}{
   600  					PublicKeyPath:              "path",
   601  					IssuerCertificatePath:      "path",
   602  					CertificateToCrossSignPath: "path",
   603  				},
   604  				Outputs: struct {
   605  					CertificatePath string `yaml:"certificate-path"`
   606  				}{
   607  					CertificatePath: "path",
   608  				},
   609  				CertProfile: certProfile{
   610  					NotBefore:          "a",
   611  					NotAfter:           "b",
   612  					SignatureAlgorithm: "c",
   613  					CommonName:         "d",
   614  					Organization:       "e",
   615  					Country:            "f",
   616  					OCSPURL:            "g",
   617  					CRLURL:             "h",
   618  					IssuerURL:          "i",
   619  					Policies:           []policyInfoConfig{{OID: "2.23.140.1.2.1"}, {OID: "6.6.6"}},
   620  				},
   621  				SkipLints: []string{},
   622  			},
   623  			expectedError: "policy should be exactly BRs domain-validated for subordinate CAs",
   624  		},
   625  		{
   626  			name: "too few policy OIDs",
   627  			config: crossCertConfig{
   628  				PKCS11: PKCS11SigningConfig{
   629  					Module:       "module",
   630  					SigningLabel: "label",
   631  				},
   632  				Inputs: struct {
   633  					PublicKeyPath              string `yaml:"public-key-path"`
   634  					IssuerCertificatePath      string `yaml:"issuer-certificate-path"`
   635  					CertificateToCrossSignPath string `yaml:"certificate-to-cross-sign-path"`
   636  				}{
   637  					PublicKeyPath:              "path",
   638  					IssuerCertificatePath:      "path",
   639  					CertificateToCrossSignPath: "path",
   640  				},
   641  				Outputs: struct {
   642  					CertificatePath string `yaml:"certificate-path"`
   643  				}{
   644  					CertificatePath: "path",
   645  				},
   646  				CertProfile: certProfile{
   647  					NotBefore:          "a",
   648  					NotAfter:           "b",
   649  					SignatureAlgorithm: "c",
   650  					CommonName:         "d",
   651  					Organization:       "e",
   652  					Country:            "f",
   653  					OCSPURL:            "g",
   654  					CRLURL:             "h",
   655  					IssuerURL:          "i",
   656  					Policies:           []policyInfoConfig{},
   657  				},
   658  				SkipLints: []string{},
   659  			},
   660  			expectedError: "policy should be exactly BRs domain-validated for subordinate CAs",
   661  		},
   662  		{
   663  			name: "good config",
   664  			config: crossCertConfig{
   665  				PKCS11: PKCS11SigningConfig{
   666  					Module:       "module",
   667  					SigningLabel: "label",
   668  				},
   669  				Inputs: struct {
   670  					PublicKeyPath              string `yaml:"public-key-path"`
   671  					IssuerCertificatePath      string `yaml:"issuer-certificate-path"`
   672  					CertificateToCrossSignPath string `yaml:"certificate-to-cross-sign-path"`
   673  				}{
   674  					PublicKeyPath:              "path",
   675  					IssuerCertificatePath:      "path",
   676  					CertificateToCrossSignPath: "path",
   677  				},
   678  				Outputs: struct {
   679  					CertificatePath string `yaml:"certificate-path"`
   680  				}{
   681  					CertificatePath: "path",
   682  				},
   683  				CertProfile: certProfile{
   684  					NotBefore:          "a",
   685  					NotAfter:           "b",
   686  					SignatureAlgorithm: "c",
   687  					CommonName:         "d",
   688  					Organization:       "e",
   689  					Country:            "f",
   690  					OCSPURL:            "g",
   691  					CRLURL:             "h",
   692  					IssuerURL:          "i",
   693  					Policies:           []policyInfoConfig{{OID: "2.23.140.1.2.1"}},
   694  				},
   695  				SkipLints: []string{},
   696  			},
   697  		},
   698  	}
   699  	for _, tc := range cases {
   700  		t.Run(tc.name, func(t *testing.T) {
   701  			err := tc.config.validate()
   702  			if err != nil && err.Error() != tc.expectedError {
   703  				t.Fatalf("Unexpected error, wanted: %q, got: %q", tc.expectedError, err)
   704  			} else if err == nil && tc.expectedError != "" {
   705  				t.Fatalf("validate didn't fail, wanted: %q", err)
   706  			}
   707  		})
   708  	}
   709  }
   710  
   711  func TestCSRConfigValidate(t *testing.T) {
   712  	cases := []struct {
   713  		name          string
   714  		config        csrConfig
   715  		expectedError string
   716  	}{
   717  		{
   718  			name:          "no pkcs11.module",
   719  			config:        csrConfig{},
   720  			expectedError: "pkcs11.module is required",
   721  		},
   722  		{
   723  			name: "no pkcs11.signing-key-label",
   724  			config: csrConfig{
   725  				PKCS11: PKCS11SigningConfig{
   726  					Module: "module",
   727  				},
   728  			},
   729  			expectedError: "pkcs11.signing-key-label is required",
   730  		},
   731  		{
   732  			name: "no inputs.public-key-path",
   733  			config: csrConfig{
   734  				PKCS11: PKCS11SigningConfig{
   735  					Module:       "module",
   736  					SigningLabel: "label",
   737  				},
   738  			},
   739  			expectedError: "inputs.public-key-path is required",
   740  		},
   741  		{
   742  			name: "no outputs.csr-path",
   743  			config: csrConfig{
   744  				PKCS11: PKCS11SigningConfig{
   745  					Module:       "module",
   746  					SigningLabel: "label",
   747  				},
   748  				Inputs: struct {
   749  					PublicKeyPath string `yaml:"public-key-path"`
   750  				}{
   751  					PublicKeyPath: "path",
   752  				},
   753  			},
   754  			expectedError: "outputs.csr-path is required",
   755  		},
   756  		{
   757  			name: "bad certificate-profile",
   758  			config: csrConfig{
   759  				PKCS11: PKCS11SigningConfig{
   760  					Module:       "module",
   761  					SigningLabel: "label",
   762  				},
   763  				Inputs: struct {
   764  					PublicKeyPath string `yaml:"public-key-path"`
   765  				}{
   766  					PublicKeyPath: "path",
   767  				},
   768  				Outputs: struct {
   769  					CSRPath string `yaml:"csr-path"`
   770  				}{
   771  					CSRPath: "path",
   772  				},
   773  			},
   774  			expectedError: "common-name is required",
   775  		},
   776  		{
   777  			name: "good config",
   778  			config: csrConfig{
   779  				PKCS11: PKCS11SigningConfig{
   780  					Module:       "module",
   781  					SigningLabel: "label",
   782  				},
   783  				Inputs: struct {
   784  					PublicKeyPath string `yaml:"public-key-path"`
   785  				}{
   786  					PublicKeyPath: "path",
   787  				},
   788  				Outputs: struct {
   789  					CSRPath string `yaml:"csr-path"`
   790  				}{
   791  					CSRPath: "path",
   792  				},
   793  				CertProfile: certProfile{
   794  					CommonName:   "d",
   795  					Organization: "e",
   796  					Country:      "f",
   797  				},
   798  			},
   799  		},
   800  	}
   801  	for _, tc := range cases {
   802  		t.Run(tc.name, func(t *testing.T) {
   803  			err := tc.config.validate()
   804  			if err != nil && err.Error() != tc.expectedError {
   805  				t.Fatalf("Unexpected error, wanted: %q, got: %q", tc.expectedError, err)
   806  			} else if err == nil && tc.expectedError != "" {
   807  				t.Fatalf("validate didn't fail, wanted: %q", err)
   808  			}
   809  		})
   810  	}
   811  }
   812  
   813  func TestKeyConfigValidate(t *testing.T) {
   814  	cases := []struct {
   815  		name          string
   816  		config        keyConfig
   817  		expectedError string
   818  	}{
   819  		{
   820  			name:          "no pkcs11.module",
   821  			config:        keyConfig{},
   822  			expectedError: "pkcs11.module is required",
   823  		},
   824  		{
   825  			name: "no pkcs11.store-key-with-label",
   826  			config: keyConfig{
   827  				PKCS11: PKCS11KeyGenConfig{
   828  					Module: "module",
   829  				},
   830  			},
   831  			expectedError: "pkcs11.store-key-with-label is required",
   832  		},
   833  		{
   834  			name: "bad key fields",
   835  			config: keyConfig{
   836  				PKCS11: PKCS11KeyGenConfig{
   837  					Module:     "module",
   838  					StoreLabel: "label",
   839  				},
   840  			},
   841  			expectedError: "key.type is required",
   842  		},
   843  		{
   844  			name: "no outputs.public-key-path",
   845  			config: keyConfig{
   846  				PKCS11: PKCS11KeyGenConfig{
   847  					Module:     "module",
   848  					StoreLabel: "label",
   849  				},
   850  				Key: keyGenConfig{
   851  					Type:         "rsa",
   852  					RSAModLength: 2048,
   853  				},
   854  			},
   855  			expectedError: "outputs.public-key-path is required",
   856  		},
   857  		{
   858  			name: "good config",
   859  			config: keyConfig{
   860  				PKCS11: PKCS11KeyGenConfig{
   861  					Module:     "module",
   862  					StoreLabel: "label",
   863  				},
   864  				Key: keyGenConfig{
   865  					Type:         "rsa",
   866  					RSAModLength: 2048,
   867  				},
   868  				Outputs: struct {
   869  					PublicKeyPath    string `yaml:"public-key-path"`
   870  					PKCS11ConfigPath string `yaml:"pkcs11-config-path"`
   871  				}{
   872  					PublicKeyPath:    "path",
   873  					PKCS11ConfigPath: "path.json",
   874  				},
   875  			},
   876  		},
   877  	}
   878  	for _, tc := range cases {
   879  		t.Run(tc.name, func(t *testing.T) {
   880  			err := tc.config.validate()
   881  			if err != nil && err.Error() != tc.expectedError {
   882  				t.Fatalf("Unexpected error, wanted: %q, got: %q", tc.expectedError, err)
   883  			} else if err == nil && tc.expectedError != "" {
   884  				t.Fatalf("validate didn't fail, wanted: %q", err)
   885  			}
   886  		})
   887  	}
   888  }
   889  
   890  func TestOCSPRespConfig(t *testing.T) {
   891  	cases := []struct {
   892  		name          string
   893  		config        ocspRespConfig
   894  		expectedError string
   895  	}{
   896  		{
   897  			name:          "no pkcs11.module",
   898  			config:        ocspRespConfig{},
   899  			expectedError: "pkcs11.module is required",
   900  		},
   901  		{
   902  			name: "no pkcs11.signing-key-label",
   903  			config: ocspRespConfig{
   904  				PKCS11: PKCS11SigningConfig{
   905  					Module: "module",
   906  				},
   907  			},
   908  			expectedError: "pkcs11.signing-key-label is required",
   909  		},
   910  		{
   911  			name: "no inputs.certificate-path",
   912  			config: ocspRespConfig{
   913  				PKCS11: PKCS11SigningConfig{
   914  					Module:       "module",
   915  					SigningLabel: "label",
   916  				},
   917  			},
   918  			expectedError: "inputs.certificate-path is required",
   919  		},
   920  		{
   921  			name: "no inputs.issuer-certificate-path",
   922  			config: ocspRespConfig{
   923  				PKCS11: PKCS11SigningConfig{
   924  					Module:       "module",
   925  					SigningLabel: "label",
   926  				},
   927  				Inputs: struct {
   928  					CertificatePath                string `yaml:"certificate-path"`
   929  					IssuerCertificatePath          string `yaml:"issuer-certificate-path"`
   930  					DelegatedIssuerCertificatePath string `yaml:"delegated-issuer-certificate-path"`
   931  				}{
   932  					CertificatePath: "path",
   933  				},
   934  			},
   935  			expectedError: "inputs.issuer-certificate-path is required",
   936  		},
   937  		{
   938  			name: "no outputs.response-path",
   939  			config: ocspRespConfig{
   940  				PKCS11: PKCS11SigningConfig{
   941  					Module:       "module",
   942  					SigningLabel: "label",
   943  				},
   944  				Inputs: struct {
   945  					CertificatePath                string `yaml:"certificate-path"`
   946  					IssuerCertificatePath          string `yaml:"issuer-certificate-path"`
   947  					DelegatedIssuerCertificatePath string `yaml:"delegated-issuer-certificate-path"`
   948  				}{
   949  					CertificatePath:       "path",
   950  					IssuerCertificatePath: "path",
   951  				},
   952  			},
   953  			expectedError: "outputs.response-path is required",
   954  		},
   955  		{
   956  			name: "no ocsp-profile.this-update",
   957  			config: ocspRespConfig{
   958  				PKCS11: PKCS11SigningConfig{
   959  					Module:       "module",
   960  					SigningLabel: "label",
   961  				},
   962  				Inputs: struct {
   963  					CertificatePath                string `yaml:"certificate-path"`
   964  					IssuerCertificatePath          string `yaml:"issuer-certificate-path"`
   965  					DelegatedIssuerCertificatePath string `yaml:"delegated-issuer-certificate-path"`
   966  				}{
   967  					CertificatePath:       "path",
   968  					IssuerCertificatePath: "path",
   969  				},
   970  				Outputs: struct {
   971  					ResponsePath string `yaml:"response-path"`
   972  				}{
   973  					ResponsePath: "path",
   974  				},
   975  			},
   976  			expectedError: "ocsp-profile.this-update is required",
   977  		},
   978  		{
   979  			name: "no ocsp-profile.next-update",
   980  			config: ocspRespConfig{
   981  				PKCS11: PKCS11SigningConfig{
   982  					Module:       "module",
   983  					SigningLabel: "label",
   984  				},
   985  				Inputs: struct {
   986  					CertificatePath                string `yaml:"certificate-path"`
   987  					IssuerCertificatePath          string `yaml:"issuer-certificate-path"`
   988  					DelegatedIssuerCertificatePath string `yaml:"delegated-issuer-certificate-path"`
   989  				}{
   990  					CertificatePath:       "path",
   991  					IssuerCertificatePath: "path",
   992  				},
   993  				Outputs: struct {
   994  					ResponsePath string `yaml:"response-path"`
   995  				}{
   996  					ResponsePath: "path",
   997  				},
   998  				OCSPProfile: struct {
   999  					ThisUpdate string `yaml:"this-update"`
  1000  					NextUpdate string `yaml:"next-update"`
  1001  					Status     string `yaml:"status"`
  1002  				}{
  1003  					ThisUpdate: "this-update",
  1004  				},
  1005  			},
  1006  			expectedError: "ocsp-profile.next-update is required",
  1007  		},
  1008  		{
  1009  			name: "no ocsp-profile.status",
  1010  			config: ocspRespConfig{
  1011  				PKCS11: PKCS11SigningConfig{
  1012  					Module:       "module",
  1013  					SigningLabel: "label",
  1014  				},
  1015  				Inputs: struct {
  1016  					CertificatePath                string `yaml:"certificate-path"`
  1017  					IssuerCertificatePath          string `yaml:"issuer-certificate-path"`
  1018  					DelegatedIssuerCertificatePath string `yaml:"delegated-issuer-certificate-path"`
  1019  				}{
  1020  					CertificatePath:       "path",
  1021  					IssuerCertificatePath: "path",
  1022  				},
  1023  				Outputs: struct {
  1024  					ResponsePath string `yaml:"response-path"`
  1025  				}{
  1026  					ResponsePath: "path",
  1027  				},
  1028  				OCSPProfile: struct {
  1029  					ThisUpdate string `yaml:"this-update"`
  1030  					NextUpdate string `yaml:"next-update"`
  1031  					Status     string `yaml:"status"`
  1032  				}{
  1033  					ThisUpdate: "this-update",
  1034  					NextUpdate: "next-update",
  1035  				},
  1036  			},
  1037  			expectedError: "ocsp-profile.status must be either \"good\" or \"revoked\"",
  1038  		},
  1039  		{
  1040  			name: "good config",
  1041  			config: ocspRespConfig{
  1042  				PKCS11: PKCS11SigningConfig{
  1043  					Module:       "module",
  1044  					SigningLabel: "label",
  1045  				},
  1046  				Inputs: struct {
  1047  					CertificatePath                string `yaml:"certificate-path"`
  1048  					IssuerCertificatePath          string `yaml:"issuer-certificate-path"`
  1049  					DelegatedIssuerCertificatePath string `yaml:"delegated-issuer-certificate-path"`
  1050  				}{
  1051  					CertificatePath:       "path",
  1052  					IssuerCertificatePath: "path",
  1053  				},
  1054  				Outputs: struct {
  1055  					ResponsePath string `yaml:"response-path"`
  1056  				}{
  1057  					ResponsePath: "path",
  1058  				},
  1059  				OCSPProfile: struct {
  1060  					ThisUpdate string `yaml:"this-update"`
  1061  					NextUpdate string `yaml:"next-update"`
  1062  					Status     string `yaml:"status"`
  1063  				}{
  1064  					ThisUpdate: "this-update",
  1065  					NextUpdate: "next-update",
  1066  					Status:     "good",
  1067  				},
  1068  			},
  1069  		},
  1070  	}
  1071  	for _, tc := range cases {
  1072  		t.Run(tc.name, func(t *testing.T) {
  1073  			err := tc.config.validate()
  1074  			if err != nil && err.Error() != tc.expectedError {
  1075  				t.Fatalf("Unexpected error, wanted: %q, got: %q", tc.expectedError, err)
  1076  			} else if err == nil && tc.expectedError != "" {
  1077  				t.Fatalf("validate didn't fail, wanted: %q", err)
  1078  			}
  1079  		})
  1080  	}
  1081  }
  1082  
  1083  func TestCRLConfig(t *testing.T) {
  1084  	cases := []struct {
  1085  		name          string
  1086  		config        crlConfig
  1087  		expectedError string
  1088  	}{
  1089  		{
  1090  			name:          "no pkcs11.module",
  1091  			config:        crlConfig{},
  1092  			expectedError: "pkcs11.module is required",
  1093  		},
  1094  		{
  1095  			name: "no pkcs11.signing-key-label",
  1096  			config: crlConfig{
  1097  				PKCS11: PKCS11SigningConfig{
  1098  					Module: "module",
  1099  				},
  1100  			},
  1101  			expectedError: "pkcs11.signing-key-label is required",
  1102  		},
  1103  		{
  1104  			name: "no inputs.issuer-certificate-path",
  1105  			config: crlConfig{
  1106  				PKCS11: PKCS11SigningConfig{
  1107  					Module:       "module",
  1108  					SigningLabel: "label",
  1109  				},
  1110  			},
  1111  			expectedError: "inputs.issuer-certificate-path is required",
  1112  		},
  1113  		{
  1114  			name: "no outputs.crl-path",
  1115  			config: crlConfig{
  1116  				PKCS11: PKCS11SigningConfig{
  1117  					Module:       "module",
  1118  					SigningLabel: "label",
  1119  				},
  1120  				Inputs: struct {
  1121  					IssuerCertificatePath string `yaml:"issuer-certificate-path"`
  1122  				}{
  1123  					IssuerCertificatePath: "path",
  1124  				},
  1125  			},
  1126  			expectedError: "outputs.crl-path is required",
  1127  		},
  1128  		{
  1129  			name: "no crl-profile.this-update",
  1130  			config: crlConfig{
  1131  				PKCS11: PKCS11SigningConfig{
  1132  					Module:       "module",
  1133  					SigningLabel: "label",
  1134  				},
  1135  				Inputs: struct {
  1136  					IssuerCertificatePath string `yaml:"issuer-certificate-path"`
  1137  				}{
  1138  					IssuerCertificatePath: "path",
  1139  				},
  1140  				Outputs: struct {
  1141  					CRLPath string `yaml:"crl-path"`
  1142  				}{
  1143  					CRLPath: "path",
  1144  				},
  1145  			},
  1146  			expectedError: "crl-profile.this-update is required",
  1147  		},
  1148  		{
  1149  			name: "no crl-profile.next-update",
  1150  			config: crlConfig{
  1151  				PKCS11: PKCS11SigningConfig{
  1152  					Module:       "module",
  1153  					SigningLabel: "label",
  1154  				},
  1155  				Inputs: struct {
  1156  					IssuerCertificatePath string `yaml:"issuer-certificate-path"`
  1157  				}{
  1158  					IssuerCertificatePath: "path",
  1159  				},
  1160  				Outputs: struct {
  1161  					CRLPath string `yaml:"crl-path"`
  1162  				}{
  1163  					CRLPath: "path",
  1164  				},
  1165  				CRLProfile: struct {
  1166  					ThisUpdate          string `yaml:"this-update"`
  1167  					NextUpdate          string `yaml:"next-update"`
  1168  					Number              int64  `yaml:"number"`
  1169  					RevokedCertificates []struct {
  1170  						CertificatePath  string `yaml:"certificate-path"`
  1171  						RevocationDate   string `yaml:"revocation-date"`
  1172  						RevocationReason int    `yaml:"revocation-reason"`
  1173  					} `yaml:"revoked-certificates"`
  1174  				}{
  1175  					ThisUpdate: "this-update",
  1176  				},
  1177  			},
  1178  			expectedError: "crl-profile.next-update is required",
  1179  		},
  1180  		{
  1181  			name: "no crl-profile.number",
  1182  			config: crlConfig{
  1183  				PKCS11: PKCS11SigningConfig{
  1184  					Module:       "module",
  1185  					SigningLabel: "label",
  1186  				},
  1187  				Inputs: struct {
  1188  					IssuerCertificatePath string `yaml:"issuer-certificate-path"`
  1189  				}{
  1190  					IssuerCertificatePath: "path",
  1191  				},
  1192  				Outputs: struct {
  1193  					CRLPath string `yaml:"crl-path"`
  1194  				}{
  1195  					CRLPath: "path",
  1196  				},
  1197  				CRLProfile: struct {
  1198  					ThisUpdate          string `yaml:"this-update"`
  1199  					NextUpdate          string `yaml:"next-update"`
  1200  					Number              int64  `yaml:"number"`
  1201  					RevokedCertificates []struct {
  1202  						CertificatePath  string `yaml:"certificate-path"`
  1203  						RevocationDate   string `yaml:"revocation-date"`
  1204  						RevocationReason int    `yaml:"revocation-reason"`
  1205  					} `yaml:"revoked-certificates"`
  1206  				}{
  1207  					ThisUpdate: "this-update",
  1208  					NextUpdate: "next-update",
  1209  				},
  1210  			},
  1211  			expectedError: "crl-profile.number must be non-zero",
  1212  		},
  1213  		{
  1214  			name: "no crl-profile.revoked-certificates.certificate-path",
  1215  			config: crlConfig{
  1216  				PKCS11: PKCS11SigningConfig{
  1217  					Module:       "module",
  1218  					SigningLabel: "label",
  1219  				},
  1220  				Inputs: struct {
  1221  					IssuerCertificatePath string `yaml:"issuer-certificate-path"`
  1222  				}{
  1223  					IssuerCertificatePath: "path",
  1224  				},
  1225  				Outputs: struct {
  1226  					CRLPath string `yaml:"crl-path"`
  1227  				}{
  1228  					CRLPath: "path",
  1229  				},
  1230  				CRLProfile: struct {
  1231  					ThisUpdate          string `yaml:"this-update"`
  1232  					NextUpdate          string `yaml:"next-update"`
  1233  					Number              int64  `yaml:"number"`
  1234  					RevokedCertificates []struct {
  1235  						CertificatePath  string `yaml:"certificate-path"`
  1236  						RevocationDate   string `yaml:"revocation-date"`
  1237  						RevocationReason int    `yaml:"revocation-reason"`
  1238  					} `yaml:"revoked-certificates"`
  1239  				}{
  1240  					ThisUpdate: "this-update",
  1241  					NextUpdate: "next-update",
  1242  					Number:     1,
  1243  					RevokedCertificates: []struct {
  1244  						CertificatePath  string `yaml:"certificate-path"`
  1245  						RevocationDate   string `yaml:"revocation-date"`
  1246  						RevocationReason int    `yaml:"revocation-reason"`
  1247  					}{{}},
  1248  				},
  1249  			},
  1250  			expectedError: "crl-profile.revoked-certificates.certificate-path is required",
  1251  		},
  1252  		{
  1253  			name: "no crl-profile.revoked-certificates.revocation-date",
  1254  			config: crlConfig{
  1255  				PKCS11: PKCS11SigningConfig{
  1256  					Module:       "module",
  1257  					SigningLabel: "label",
  1258  				},
  1259  				Inputs: struct {
  1260  					IssuerCertificatePath string `yaml:"issuer-certificate-path"`
  1261  				}{
  1262  					IssuerCertificatePath: "path",
  1263  				},
  1264  				Outputs: struct {
  1265  					CRLPath string `yaml:"crl-path"`
  1266  				}{
  1267  					CRLPath: "path",
  1268  				},
  1269  				CRLProfile: struct {
  1270  					ThisUpdate          string `yaml:"this-update"`
  1271  					NextUpdate          string `yaml:"next-update"`
  1272  					Number              int64  `yaml:"number"`
  1273  					RevokedCertificates []struct {
  1274  						CertificatePath  string `yaml:"certificate-path"`
  1275  						RevocationDate   string `yaml:"revocation-date"`
  1276  						RevocationReason int    `yaml:"revocation-reason"`
  1277  					} `yaml:"revoked-certificates"`
  1278  				}{
  1279  					ThisUpdate: "this-update",
  1280  					NextUpdate: "next-update",
  1281  					Number:     1,
  1282  					RevokedCertificates: []struct {
  1283  						CertificatePath  string `yaml:"certificate-path"`
  1284  						RevocationDate   string `yaml:"revocation-date"`
  1285  						RevocationReason int    `yaml:"revocation-reason"`
  1286  					}{{
  1287  						CertificatePath: "path",
  1288  					}},
  1289  				},
  1290  			},
  1291  			expectedError: "crl-profile.revoked-certificates.revocation-date is required",
  1292  		},
  1293  		{
  1294  			name: "no revocation reason",
  1295  			config: crlConfig{
  1296  				PKCS11: PKCS11SigningConfig{
  1297  					Module:       "module",
  1298  					SigningLabel: "label",
  1299  				},
  1300  				Inputs: struct {
  1301  					IssuerCertificatePath string `yaml:"issuer-certificate-path"`
  1302  				}{
  1303  					IssuerCertificatePath: "path",
  1304  				},
  1305  				Outputs: struct {
  1306  					CRLPath string `yaml:"crl-path"`
  1307  				}{
  1308  					CRLPath: "path",
  1309  				},
  1310  				CRLProfile: struct {
  1311  					ThisUpdate          string `yaml:"this-update"`
  1312  					NextUpdate          string `yaml:"next-update"`
  1313  					Number              int64  `yaml:"number"`
  1314  					RevokedCertificates []struct {
  1315  						CertificatePath  string `yaml:"certificate-path"`
  1316  						RevocationDate   string `yaml:"revocation-date"`
  1317  						RevocationReason int    `yaml:"revocation-reason"`
  1318  					} `yaml:"revoked-certificates"`
  1319  				}{
  1320  					ThisUpdate: "this-update",
  1321  					NextUpdate: "next-update",
  1322  					Number:     1,
  1323  					RevokedCertificates: []struct {
  1324  						CertificatePath  string `yaml:"certificate-path"`
  1325  						RevocationDate   string `yaml:"revocation-date"`
  1326  						RevocationReason int    `yaml:"revocation-reason"`
  1327  					}{{
  1328  						CertificatePath: "path",
  1329  						RevocationDate:  "date",
  1330  					}},
  1331  				},
  1332  			},
  1333  			expectedError: "crl-profile.revoked-certificates.revocation-reason is required",
  1334  		},
  1335  		{
  1336  			name: "good",
  1337  			config: crlConfig{
  1338  				PKCS11: PKCS11SigningConfig{
  1339  					Module:       "module",
  1340  					SigningLabel: "label",
  1341  				},
  1342  				Inputs: struct {
  1343  					IssuerCertificatePath string `yaml:"issuer-certificate-path"`
  1344  				}{
  1345  					IssuerCertificatePath: "path",
  1346  				},
  1347  				Outputs: struct {
  1348  					CRLPath string `yaml:"crl-path"`
  1349  				}{
  1350  					CRLPath: "path",
  1351  				},
  1352  				CRLProfile: struct {
  1353  					ThisUpdate          string `yaml:"this-update"`
  1354  					NextUpdate          string `yaml:"next-update"`
  1355  					Number              int64  `yaml:"number"`
  1356  					RevokedCertificates []struct {
  1357  						CertificatePath  string `yaml:"certificate-path"`
  1358  						RevocationDate   string `yaml:"revocation-date"`
  1359  						RevocationReason int    `yaml:"revocation-reason"`
  1360  					} `yaml:"revoked-certificates"`
  1361  				}{
  1362  					ThisUpdate: "this-update",
  1363  					NextUpdate: "next-update",
  1364  					Number:     1,
  1365  					RevokedCertificates: []struct {
  1366  						CertificatePath  string `yaml:"certificate-path"`
  1367  						RevocationDate   string `yaml:"revocation-date"`
  1368  						RevocationReason int    `yaml:"revocation-reason"`
  1369  					}{{
  1370  						CertificatePath:  "path",
  1371  						RevocationDate:   "date",
  1372  						RevocationReason: 1,
  1373  					}},
  1374  				},
  1375  			},
  1376  		},
  1377  	}
  1378  	for _, tc := range cases {
  1379  		t.Run(tc.name, func(t *testing.T) {
  1380  			err := tc.config.validate()
  1381  			if err != nil && err.Error() != tc.expectedError {
  1382  				t.Fatalf("Unexpected error, wanted: %q, got: %q", tc.expectedError, err)
  1383  			} else if err == nil && tc.expectedError != "" {
  1384  				t.Fatalf("validate didn't fail, wanted: %q", err)
  1385  			}
  1386  		})
  1387  	}
  1388  }
  1389  
  1390  func TestSignAndWriteNoLintCert(t *testing.T) {
  1391  	_, err := signAndWriteCert(nil, nil, nil, nil, nil, "")
  1392  	test.AssertError(t, err, "should have failed because no lintCert was provided")
  1393  	test.AssertDeepEquals(t, err, fmt.Errorf("linting was not performed prior to issuance"))
  1394  }
  1395  

View as plain text