@@ -2,7 +2,10 @@ package hashicorpvault
2
2
3
3
import (
4
4
"bytes"
5
+ "context"
5
6
"fmt"
7
+ "github.com/hashicorp/vault/sdk/helper/consts"
8
+ "github.com/spiffe/spire/pkg/server/plugin/keymanager"
6
9
"github.com/stretchr/testify/require"
7
10
"google.golang.org/grpc/codes"
8
11
"testing"
@@ -251,6 +254,283 @@ func TestConfigure(t *testing.T) {
251
254
}
252
255
}
253
256
257
+ func TestGenerateKey (t * testing.T ) {
258
+ successfulConfig := & Config {
259
+ TransitEnginePath : "test-transit" ,
260
+ CACertPath : "testdata/root-cert.pem" ,
261
+ TokenAuth : & TokenAuthConfig {
262
+ Token : "test-token" ,
263
+ },
264
+ }
265
+
266
+ for _ , tt := range []struct {
267
+ name string
268
+ csr []byte
269
+ config * Config
270
+ authMethod AuthMethod
271
+ expectCode codes.Code
272
+ expectMsgPrefix string
273
+ id string
274
+ keyType keymanager.KeyType
275
+
276
+ fakeServer func () * FakeVaultServerConfig
277
+ }{
278
+ {
279
+ name : "Generate EC P-256 key with token auth" ,
280
+ id : "x509-CA-A" ,
281
+ keyType : keymanager .ECP256 ,
282
+ config : successfulConfig ,
283
+ authMethod : TOKEN ,
284
+ fakeServer : func () * FakeVaultServerConfig {
285
+ fakeServer := setupSuccessFakeVaultServer ()
286
+ fakeServer .LookupSelfResponse = []byte (testLookupSelfResponse )
287
+ fakeServer .CertAuthResponse = []byte {}
288
+ fakeServer .AppRoleAuthResponse = []byte {}
289
+
290
+ return fakeServer
291
+ },
292
+ },
293
+ {
294
+ name : "Generate P-384 key with token auth" ,
295
+ id : "x509-CA-A" ,
296
+ keyType : keymanager .ECP384 ,
297
+ config : successfulConfig ,
298
+ authMethod : TOKEN ,
299
+ fakeServer : func () * FakeVaultServerConfig {
300
+ fakeServer := setupSuccessFakeVaultServer ()
301
+ fakeServer .LookupSelfResponse = []byte (testLookupSelfResponse )
302
+ fakeServer .CertAuthResponse = []byte {}
303
+ fakeServer .AppRoleAuthResponse = []byte {}
304
+ fakeServer .GetKeyResponse = []byte (testGetKeyResponseP384 )
305
+
306
+ return fakeServer
307
+ },
308
+ },
309
+ {
310
+ name : "Generate RSA 2048 key with token auth" ,
311
+ id : "x509-CA-A" ,
312
+ keyType : keymanager .RSA2048 ,
313
+ config : successfulConfig ,
314
+ authMethod : TOKEN ,
315
+ fakeServer : func () * FakeVaultServerConfig {
316
+ fakeServer := setupSuccessFakeVaultServer ()
317
+ fakeServer .LookupSelfResponse = []byte (testLookupSelfResponse )
318
+ fakeServer .CertAuthResponse = []byte {}
319
+ fakeServer .AppRoleAuthResponse = []byte {}
320
+ fakeServer .GetKeyResponse = []byte (testGetKeyResponseRSA2048 )
321
+
322
+ return fakeServer
323
+ },
324
+ },
325
+ {
326
+ name : "Generate RSA 4096 key with token auth" ,
327
+ id : "x509-CA-A" ,
328
+ keyType : keymanager .RSA4096 ,
329
+ config : successfulConfig ,
330
+ authMethod : TOKEN ,
331
+ fakeServer : func () * FakeVaultServerConfig {
332
+ fakeServer := setupSuccessFakeVaultServer ()
333
+ fakeServer .LookupSelfResponse = []byte (testLookupSelfResponse )
334
+ fakeServer .CertAuthResponse = []byte {}
335
+ fakeServer .AppRoleAuthResponse = []byte {}
336
+ fakeServer .GetKeyResponse = []byte (testGetKeyResponseRSA4096 )
337
+
338
+ return fakeServer
339
+ },
340
+ },
341
+ {
342
+ name : "Generate key with missing id" ,
343
+ keyType : keymanager .RSA2048 ,
344
+ config : successfulConfig ,
345
+ authMethod : TOKEN ,
346
+ fakeServer : func () * FakeVaultServerConfig {
347
+ fakeServer := setupSuccessFakeVaultServer ()
348
+ fakeServer .LookupSelfResponse = []byte (testLookupSelfResponse )
349
+ fakeServer .CertAuthResponse = []byte {}
350
+ fakeServer .AppRoleAuthResponse = []byte {}
351
+ fakeServer .GetKeyResponse = []byte (testGetKeyResponseRSA2048 )
352
+
353
+ return fakeServer
354
+ },
355
+ expectCode : codes .InvalidArgument ,
356
+ expectMsgPrefix : "keymanager(hashicorp_vault): key id is required" ,
357
+ },
358
+ {
359
+ name : "Generate key with missing key type" ,
360
+ id : "x509-CA-A" ,
361
+ config : successfulConfig ,
362
+ authMethod : TOKEN ,
363
+ fakeServer : func () * FakeVaultServerConfig {
364
+ fakeServer := setupSuccessFakeVaultServer ()
365
+ fakeServer .LookupSelfResponse = []byte (testLookupSelfResponse )
366
+ fakeServer .CertAuthResponse = []byte {}
367
+ fakeServer .AppRoleAuthResponse = []byte {}
368
+ fakeServer .GetKeyResponse = []byte (testGetKeyResponseRSA2048 )
369
+
370
+ return fakeServer
371
+ },
372
+ expectCode : codes .InvalidArgument ,
373
+ expectMsgPrefix : "keymanager(hashicorp_vault): key type is required" ,
374
+ },
375
+ {
376
+ name : "Generate key with unsupported key type" ,
377
+ id : "x509-CA-A" ,
378
+ keyType : 100 ,
379
+ config : successfulConfig ,
380
+ authMethod : TOKEN ,
381
+ fakeServer : func () * FakeVaultServerConfig {
382
+ fakeServer := setupSuccessFakeVaultServer ()
383
+ fakeServer .LookupSelfResponse = []byte (testLookupSelfResponse )
384
+ fakeServer .CertAuthResponse = []byte {}
385
+ fakeServer .AppRoleAuthResponse = []byte {}
386
+ fakeServer .GetKeyResponse = []byte (testGetKeyResponseRSA2048 )
387
+
388
+ return fakeServer
389
+ },
390
+ expectCode : codes .Internal ,
391
+ expectMsgPrefix : "keymanager(hashicorp_vault): facade does not support key type \" UNKNOWN(100)\" " ,
392
+ },
393
+ {
394
+ name : "Malformed get key response" ,
395
+ id : "x509-CA-A" ,
396
+ keyType : keymanager .RSA2048 ,
397
+ config : successfulConfig ,
398
+ authMethod : TOKEN ,
399
+ fakeServer : func () * FakeVaultServerConfig {
400
+ fakeServer := setupSuccessFakeVaultServer ()
401
+ fakeServer .LookupSelfResponse = []byte (testLookupSelfResponse )
402
+ fakeServer .CertAuthResponse = []byte {}
403
+ fakeServer .AppRoleAuthResponse = []byte {}
404
+ fakeServer .GetKeyResponse = []byte ("error" )
405
+
406
+ return fakeServer
407
+ },
408
+ expectCode : codes .Internal ,
409
+ expectMsgPrefix : "keymanager(hashicorp_vault): failed to get transit engine key: invalid character" ,
410
+ },
411
+ {
412
+ name : "Malformed create key response" ,
413
+ id : "x509-CA-A" ,
414
+ keyType : keymanager .RSA2048 ,
415
+ config : successfulConfig ,
416
+ authMethod : TOKEN ,
417
+ fakeServer : func () * FakeVaultServerConfig {
418
+ fakeServer := setupSuccessFakeVaultServer ()
419
+ fakeServer .LookupSelfResponse = []byte (testLookupSelfResponse )
420
+ fakeServer .CertAuthResponse = []byte {}
421
+ fakeServer .AppRoleAuthResponse = []byte {}
422
+ fakeServer .CreateKeyResponse = []byte ("error" )
423
+
424
+ return fakeServer
425
+ },
426
+ expectCode : codes .Internal ,
427
+ expectMsgPrefix : "keymanager(hashicorp_vault): failed to create transit engine key: invalid character" ,
428
+ },
429
+ {
430
+ name : "Bad get key response code" ,
431
+ id : "x509-CA-A" ,
432
+ keyType : keymanager .RSA2048 ,
433
+ config : successfulConfig ,
434
+ authMethod : TOKEN ,
435
+ fakeServer : func () * FakeVaultServerConfig {
436
+ fakeServer := setupSuccessFakeVaultServer ()
437
+ fakeServer .LookupSelfResponse = []byte (testLookupSelfResponse )
438
+ fakeServer .CertAuthResponse = []byte {}
439
+ fakeServer .AppRoleAuthResponse = []byte {}
440
+ fakeServer .GetKeyResponseCode = 500
441
+
442
+ return fakeServer
443
+ },
444
+ expectCode : codes .Internal ,
445
+ expectMsgPrefix : "keymanager(hashicorp_vault): failed to get transit engine key: Error making API request." ,
446
+ },
447
+ {
448
+ name : "Bad create key response code" ,
449
+ id : "x509-CA-A" ,
450
+ keyType : keymanager .RSA2048 ,
451
+ config : successfulConfig ,
452
+ authMethod : TOKEN ,
453
+ fakeServer : func () * FakeVaultServerConfig {
454
+ fakeServer := setupSuccessFakeVaultServer ()
455
+ fakeServer .LookupSelfResponse = []byte (testLookupSelfResponse )
456
+ fakeServer .CertAuthResponse = []byte {}
457
+ fakeServer .AppRoleAuthResponse = []byte {}
458
+ fakeServer .CreateKeyResponseCode = 500
459
+
460
+ return fakeServer
461
+ },
462
+ expectCode : codes .Internal ,
463
+ expectMsgPrefix : "keymanager(hashicorp_vault): failed to create transit engine key: Error making API request." ,
464
+ },
465
+ {
466
+ name : "Malformed key" ,
467
+ id : "x509-CA-A" ,
468
+ keyType : keymanager .RSA2048 ,
469
+ config : successfulConfig ,
470
+ authMethod : TOKEN ,
471
+ fakeServer : func () * FakeVaultServerConfig {
472
+ fakeServer := setupSuccessFakeVaultServer ()
473
+ fakeServer .LookupSelfResponse = []byte (testLookupSelfResponse )
474
+ fakeServer .CertAuthResponse = []byte {}
475
+ fakeServer .AppRoleAuthResponse = []byte {}
476
+ fakeServer .GetKeyResponse = []byte (testGetKeyResponseMalformed )
477
+
478
+ return fakeServer
479
+ },
480
+ expectCode : codes .Internal ,
481
+ expectMsgPrefix : "keymanager(hashicorp_vault): unable to decode PEM key" ,
482
+ },
483
+ } {
484
+ tt := tt
485
+ t .Run (tt .name , func (t * testing.T ) {
486
+ fakeVaultServer := tt .fakeServer ()
487
+
488
+ s , addr , err := fakeVaultServer .NewTLSServer ()
489
+ require .NoError (t , err )
490
+
491
+ s .Start ()
492
+ defer s .Close ()
493
+
494
+ p := New ()
495
+ options := []plugintest.Option {
496
+ plugintest .CaptureConfigureError (& err ),
497
+ plugintest .CoreConfig (catalog.CoreConfig {TrustDomain : spiffeid .RequireTrustDomainFromString ("example.org" )}),
498
+ }
499
+ if tt .config != nil {
500
+ tt .config .VaultAddr = fmt .Sprintf ("https://%s" , addr )
501
+ cp , err := p .genClientParams (tt .authMethod , tt .config )
502
+ require .NoError (t , err )
503
+ cc , err := NewClientConfig (cp , p .logger )
504
+ require .NoError (t , err )
505
+ p .cc = cc
506
+ options = append (options , plugintest .ConfigureJSON (tt .config ))
507
+ }
508
+ p .authMethod = tt .authMethod
509
+
510
+ v1 := new (keymanager.V1 )
511
+ plugintest .Load (t , builtin (p ), v1 ,
512
+ options ... ,
513
+ )
514
+
515
+ key , err := v1 .GenerateKey (context .Background (), tt .id , tt .keyType )
516
+
517
+ spiretest .RequireGRPCStatusHasPrefix (t , err , tt .expectCode , tt .expectMsgPrefix )
518
+ if tt .expectCode != codes .OK {
519
+ require .Nil (t , key )
520
+ return
521
+ }
522
+
523
+ require .NotNil (t , key )
524
+ require .Equal (t , tt .id , key .ID ())
525
+
526
+ if p .cc .clientParams .Namespace != "" {
527
+ headers := p .vc .vaultClient .Headers ()
528
+ require .Equal (t , p .cc .clientParams .Namespace , headers .Get (consts .NamespaceHeaderName ))
529
+ }
530
+ })
531
+ }
532
+ }
533
+
254
534
func getTestConfigureRequest (t * testing.T , addr string , tpl string ) string {
255
535
templ , err := template .New ("plugin config" ).Parse (tpl )
256
536
require .NoError (t , err )
@@ -264,6 +544,35 @@ func getTestConfigureRequest(t *testing.T, addr string, tpl string) string {
264
544
return c .String ()
265
545
}
266
546
547
+ func setupSuccessFakeVaultServer () * FakeVaultServerConfig {
548
+ fakeVaultServer := setupFakeVaultServer ()
549
+
550
+ fakeVaultServer .CertAuthResponseCode = 200
551
+ fakeVaultServer .CertAuthResponse = []byte (testCertAuthResponse )
552
+ fakeVaultServer .CertAuthReqEndpoint = "/v1/auth/test-cert-auth/login"
553
+
554
+ fakeVaultServer .AppRoleAuthResponseCode = 200
555
+ fakeVaultServer .AppRoleAuthResponse = []byte (testAppRoleAuthResponse )
556
+ fakeVaultServer .AppRoleAuthReqEndpoint = "/v1/auth/test-approle-auth/login"
557
+
558
+ fakeVaultServer .K8sAuthResponseCode = 200
559
+ fakeVaultServer .K8sAuthReqEndpoint = "/v1/auth/test-k8s-auth/login"
560
+ fakeVaultServer .K8sAuthResponse = []byte (testK8sAuthResponse )
561
+
562
+ fakeVaultServer .LookupSelfResponse = []byte (testLookupSelfResponse )
563
+ fakeVaultServer .LookupSelfReqEndpoint = "GET /v1/auth/token/lookup-self"
564
+ fakeVaultServer .LookupSelfResponseCode = 200
565
+
566
+ fakeVaultServer .CreateKeyResponseCode = 200
567
+ fakeVaultServer .CreateKeyReqEndpoint = "PUT /v1/test-transit/keys/{id}"
568
+
569
+ fakeVaultServer .GetKeyResponseCode = 200
570
+ fakeVaultServer .GetKeyReqEndpoint = "GET /v1/test-transit/keys/{id}"
571
+ fakeVaultServer .GetKeyResponse = []byte (testGetKeyResponseP256 )
572
+
573
+ return fakeVaultServer
574
+ }
575
+
267
576
func setupFakeVaultServer () * FakeVaultServerConfig {
268
577
fakeVaultServer := NewFakeVaultServerConfig ()
269
578
fakeVaultServer .ServerCertificatePemPath = testServerCert
0 commit comments