@@ -166,8 +166,7 @@ func TestRunCreate(t *testing.T) {
166166 "issuer": {
167167 "commonName": "Test TSA Root CA"
168168 },
169- "notBefore": "2024-01-01T00:00:00Z",
170- "notAfter": "2025-01-01T00:00:00Z",
169+ "certLife": "8760h",
171170 "keyUsage": ["certSign", "crlSign"],
172171 "basicConstraints": {
173172 "isCA": true,
@@ -179,8 +178,10 @@ func TestRunCreate(t *testing.T) {
179178 "subject": {
180179 "commonName": "Test TSA"
181180 },
182- "notBefore": "2024-01-01T00:00:00Z",
183- "notAfter": "2025-01-01T00:00:00Z",
181+ "issuer": {
182+ "commonName": "Test TSA Root CA"
183+ },
184+ "certLife": "8760h",
184185 "keyUsage": ["digitalSignature"],
185186 "extKeyUsage": ["TimeStamping"],
186187 "basicConstraints": {
@@ -324,7 +325,7 @@ func TestRunCreate(t *testing.T) {
324325 viper .Reset ()
325326 cmd := & cobra.Command {}
326327 for i := 0 ; i < len (tt .args ); i += 2 {
327- flag := tt .args [i ][2 :] // Remove "--" prefix
328+ flag := tt .args [i ][2 :]
328329 value := tt .args [i + 1 ]
329330 viper .Set (flag , value )
330331 }
@@ -352,8 +353,7 @@ func TestCreateCommand(t *testing.T) {
352353 "issuer": {
353354 "commonName": "Test TSA Root CA"
354355 },
355- "notBefore": "2024-01-01T00:00:00Z",
356- "notAfter": "2025-01-01T00:00:00Z",
356+ "certLife": "8760h",
357357 "keyUsage": ["certSign", "crlSign"],
358358 "basicConstraints": {
359359 "isCA": true,
@@ -365,8 +365,10 @@ func TestCreateCommand(t *testing.T) {
365365 "subject": {
366366 "commonName": "Test TSA"
367367 },
368- "notBefore": "2024-01-01T00:00:00Z",
369- "notAfter": "2025-01-01T00:00:00Z",
368+ "issuer": {
369+ "commonName": "Test TSA Root CA"
370+ },
371+ "certLife": "8760h",
370372 "keyUsage": ["digitalSignature"],
371373 "extKeyUsage": ["TimeStamping"],
372374 "basicConstraints": {
@@ -432,7 +434,7 @@ func TestCreateCommand(t *testing.T) {
432434 viper .Reset ()
433435 cmd := & cobra.Command {}
434436 for i := 0 ; i < len (tt .args ); i += 2 {
435- flag := tt .args [i ][2 :] // Remove "--" prefix
437+ flag := tt .args [i ][2 :]
436438 value := tt .args [i + 1 ]
437439 viper .Set (flag , value )
438440 }
@@ -479,3 +481,239 @@ func TestRootCommand(t *testing.T) {
479481 })
480482 }
481483}
484+
485+ func TestEnvironmentVariableHandling (t * testing.T ) {
486+ tests := []struct {
487+ name string
488+ envVars map [string ]string
489+ args []string
490+ wantError bool
491+ errorString string
492+ }{
493+ {
494+ name : "AWS KMS from environment" ,
495+ envVars : map [string ]string {
496+ "KMS_TYPE" : "awskms" ,
497+ "AWS_REGION" : "us-west-2" ,
498+ "KMS_ROOT_KEY_ID" : "alias/test-root" ,
499+ "KMS_LEAF_KEY_ID" : "alias/test-leaf" ,
500+ },
501+ args : []string {"create" },
502+ wantError : true ,
503+ },
504+ {
505+ name : "GCP KMS from environment" ,
506+ envVars : map [string ]string {
507+ "KMS_TYPE" : "gcpkms" ,
508+ "GCP_CREDENTIALS_FILE" : "/path/to/creds.json" ,
509+ "KMS_ROOT_KEY_ID" : "projects/test/locations/global/keyRings/test/cryptoKeys/root/cryptoKeyVersions/1" ,
510+ "KMS_LEAF_KEY_ID" : "projects/test/locations/global/keyRings/test/cryptoKeys/leaf/cryptoKeyVersions/1" ,
511+ },
512+ args : []string {"create" },
513+ wantError : true ,
514+ errorString : "credentials file not found" ,
515+ },
516+ {
517+ name : "Azure KMS from environment" ,
518+ envVars : map [string ]string {
519+ "KMS_TYPE" : "azurekms" ,
520+ "AZURE_TENANT_ID" : "test-tenant" ,
521+ "KMS_ROOT_KEY_ID" : "azurekms:name=test-key;vault=test-vault" ,
522+ "KMS_LEAF_KEY_ID" : "azurekms:name=test-key;vault=test-vault" ,
523+ },
524+ args : []string {"create" },
525+ wantError : true ,
526+ },
527+ {
528+ name : "HashiVault KMS from environment" ,
529+ envVars : map [string ]string {
530+ "KMS_TYPE" : "hashivault" ,
531+ "VAULT_TOKEN" : "test-token" ,
532+ "VAULT_ADDR" : "http://vault:8200" ,
533+ "KMS_ROOT_KEY_ID" : "transit/keys/test-root" ,
534+ "KMS_LEAF_KEY_ID" : "transit/keys/test-leaf" ,
535+ },
536+ args : []string {"create" },
537+ wantError : true ,
538+ },
539+ }
540+
541+ for _ , tt := range tests {
542+ t .Run (tt .name , func (t * testing.T ) {
543+ oldEnv := map [string ]string {}
544+ for k := range tt .envVars {
545+ if v , ok := os .LookupEnv (k ); ok {
546+ oldEnv [k ] = v
547+ }
548+ }
549+
550+ for k , v := range tt .envVars {
551+ os .Setenv (k , v )
552+ }
553+
554+ viper .Reset ()
555+
556+ viper .BindEnv ("kms-type" , "KMS_TYPE" )
557+ viper .BindEnv ("aws-region" , "AWS_REGION" )
558+ viper .BindEnv ("azure-tenant-id" , "AZURE_TENANT_ID" )
559+ viper .BindEnv ("gcp-credentials-file" , "GCP_CREDENTIALS_FILE" )
560+ viper .BindEnv ("vault-token" , "VAULT_TOKEN" )
561+ viper .BindEnv ("vault-address" , "VAULT_ADDR" )
562+ viper .BindEnv ("root-key-id" , "KMS_ROOT_KEY_ID" )
563+ viper .BindEnv ("leaf-key-id" , "KMS_LEAF_KEY_ID" )
564+
565+ defer func () {
566+ for k := range tt .envVars {
567+ if v , ok := oldEnv [k ]; ok {
568+ os .Setenv (k , v )
569+ } else {
570+ os .Unsetenv (k )
571+ }
572+ }
573+ }()
574+
575+ cmd := & cobra.Command {
576+ Use : "test" ,
577+ RunE : runCreate ,
578+ }
579+
580+ cmd .Flags ().String ("kms-type" , "" , "KMS type" )
581+ cmd .Flags ().String ("aws-region" , "" , "AWS region" )
582+ cmd .Flags ().String ("azure-tenant-id" , "" , "Azure tenant ID" )
583+ cmd .Flags ().String ("gcp-credentials-file" , "" , "GCP credentials file" )
584+ cmd .Flags ().String ("vault-token" , "" , "HashiVault token" )
585+ cmd .Flags ().String ("vault-address" , "" , "HashiVault address" )
586+ cmd .Flags ().String ("root-key-id" , "" , "Root key ID" )
587+ cmd .Flags ().String ("leaf-key-id" , "" , "Leaf key ID" )
588+ cmd .Flags ().String ("root-template" , "templates/root-template.json" , "Root template" )
589+ cmd .Flags ().String ("leaf-template" , "templates/leaf-template.json" , "Leaf template" )
590+
591+ viper .BindPFlag ("kms-type" , cmd .Flags ().Lookup ("kms-type" ))
592+ viper .BindPFlag ("aws-region" , cmd .Flags ().Lookup ("aws-region" ))
593+ viper .BindPFlag ("azure-tenant-id" , cmd .Flags ().Lookup ("azure-tenant-id" ))
594+ viper .BindPFlag ("gcp-credentials-file" , cmd .Flags ().Lookup ("gcp-credentials-file" ))
595+ viper .BindPFlag ("vault-token" , cmd .Flags ().Lookup ("vault-token" ))
596+ viper .BindPFlag ("vault-address" , cmd .Flags ().Lookup ("vault-address" ))
597+ viper .BindPFlag ("root-key-id" , cmd .Flags ().Lookup ("root-key-id" ))
598+ viper .BindPFlag ("leaf-key-id" , cmd .Flags ().Lookup ("leaf-key-id" ))
599+ viper .BindPFlag ("root-template" , cmd .Flags ().Lookup ("root-template" ))
600+ viper .BindPFlag ("leaf-template" , cmd .Flags ().Lookup ("leaf-template" ))
601+
602+ cmd .SetArgs (tt .args )
603+ err := cmd .Execute ()
604+
605+ if tt .wantError {
606+ require .Error (t , err )
607+ if tt .errorString != "" {
608+ assert .Contains (t , err .Error (), tt .errorString )
609+ }
610+ } else {
611+ require .NoError (t , err )
612+ }
613+
614+ assert .Equal (t , tt .envVars ["KMS_TYPE" ], viper .GetString ("kms-type" ))
615+ assert .Equal (t , tt .envVars ["KMS_ROOT_KEY_ID" ], viper .GetString ("root-key-id" ))
616+ assert .Equal (t , tt .envVars ["KMS_LEAF_KEY_ID" ], viper .GetString ("leaf-key-id" ))
617+ })
618+ }
619+ }
620+
621+ func TestKMSProviderConfigurationValidation (t * testing.T ) {
622+ tests := []struct {
623+ name string
624+ args []string
625+ wantError bool
626+ errorString string
627+ }{
628+ {
629+ name : "AWS KMS invalid key format" ,
630+ args : []string {
631+ "create" ,
632+ "--kms-type" , "awskms" ,
633+ "--aws-region" , "us-west-2" ,
634+ "--root-key-id" , "invalid-format" ,
635+ "--leaf-key-id" , "invalid-format" ,
636+ },
637+ wantError : true ,
638+ errorString : "must start with 'arn:aws:kms:' or 'alias/'" ,
639+ },
640+ {
641+ name : "GCP KMS missing key version" ,
642+ args : []string {
643+ "create" ,
644+ "--kms-type" , "gcpkms" ,
645+ "--root-key-id" , "projects/test/locations/global/keyRings/test/cryptoKeys/test" ,
646+ "--leaf-key-id" , "projects/test/locations/global/keyRings/test/cryptoKeys/test" ,
647+ },
648+ wantError : true ,
649+ errorString : "must contain '/cryptoKeyVersions/'" ,
650+ },
651+ {
652+ name : "Azure KMS invalid key format" ,
653+ args : []string {
654+ "create" ,
655+ "--kms-type" , "azurekms" ,
656+ "--azure-tenant-id" , "test-tenant" ,
657+ "--root-key-id" , "invalid-format" ,
658+ "--leaf-key-id" , "invalid-format" ,
659+ },
660+ wantError : true ,
661+ errorString : "must start with 'azurekms:name='" ,
662+ },
663+ {
664+ name : "HashiVault KMS invalid key path" ,
665+ args : []string {
666+ "create" ,
667+ "--kms-type" , "hashivault" ,
668+ "--vault-token" , "test-token" ,
669+ "--vault-address" , "http://vault:8200" ,
670+ "--root-key-id" , "invalid/path" ,
671+ "--leaf-key-id" , "invalid/path" ,
672+ },
673+ wantError : true ,
674+ errorString : "must be in format: transit/keys/keyname" ,
675+ },
676+ }
677+
678+ for _ , tt := range tests {
679+ t .Run (tt .name , func (t * testing.T ) {
680+ viper .Reset ()
681+ cmd := & cobra.Command {
682+ Use : "test" ,
683+ RunE : runCreate ,
684+ }
685+
686+ cmd .Flags ().String ("kms-type" , "" , "KMS type" )
687+ cmd .Flags ().String ("aws-region" , "" , "AWS region" )
688+ cmd .Flags ().String ("azure-tenant-id" , "" , "Azure tenant ID" )
689+ cmd .Flags ().String ("vault-token" , "" , "HashiVault token" )
690+ cmd .Flags ().String ("vault-address" , "" , "HashiVault address" )
691+ cmd .Flags ().String ("root-key-id" , "" , "Root key ID" )
692+ cmd .Flags ().String ("leaf-key-id" , "" , "Leaf key ID" )
693+ cmd .Flags ().String ("root-template" , "templates/root-template.json" , "Root template" )
694+ cmd .Flags ().String ("leaf-template" , "templates/leaf-template.json" , "Leaf template" )
695+
696+ viper .BindPFlag ("kms-type" , cmd .Flags ().Lookup ("kms-type" ))
697+ viper .BindPFlag ("aws-region" , cmd .Flags ().Lookup ("aws-region" ))
698+ viper .BindPFlag ("azure-tenant-id" , cmd .Flags ().Lookup ("azure-tenant-id" ))
699+ viper .BindPFlag ("vault-token" , cmd .Flags ().Lookup ("vault-token" ))
700+ viper .BindPFlag ("vault-address" , cmd .Flags ().Lookup ("vault-address" ))
701+ viper .BindPFlag ("root-key-id" , cmd .Flags ().Lookup ("root-key-id" ))
702+ viper .BindPFlag ("leaf-key-id" , cmd .Flags ().Lookup ("leaf-key-id" ))
703+ viper .BindPFlag ("root-template" , cmd .Flags ().Lookup ("root-template" ))
704+ viper .BindPFlag ("leaf-template" , cmd .Flags ().Lookup ("leaf-template" ))
705+
706+ cmd .SetArgs (tt .args )
707+ err := cmd .Execute ()
708+
709+ if tt .wantError {
710+ require .Error (t , err )
711+ if tt .errorString != "" {
712+ assert .Contains (t , err .Error (), tt .errorString )
713+ }
714+ } else {
715+ require .NoError (t , err )
716+ }
717+ })
718+ }
719+ }
0 commit comments