diff --git a/keymanager/km_common/src/key_types.rs b/keymanager/km_common/src/key_types.rs index 0ac7b23ec..f0536dde1 100644 --- a/keymanager/km_common/src/key_types.rs +++ b/keymanager/km_common/src/key_types.rs @@ -213,33 +213,6 @@ mod tests { use super::*; use crate::algorithms::{AeadAlgorithm, KdfAlgorithm, KemAlgorithm}; - fn create_key_record( - algo: HpkeAlgorithm, - expiry_secs: u64, - spec_builder: F, - ) -> Result - where - F: FnOnce(HpkeAlgorithm, PublicKey) -> KeySpec, - { - let (pub_key, priv_key) = crypto::generate_keypair(KemAlgorithm::DhkemX25519HkdfSha256)?; - let id = Uuid::new_v4(); - let vault = Vault::new(secret_box::SecretBox::from(priv_key)) - .map_err(|_| crypto::Error::CryptoError)?; - let now = Instant::now(); - let delete_after = now - .checked_add(Duration::from_secs(expiry_secs)) - .ok_or(crypto::Error::UnsupportedAlgorithm)?; - Ok(KeyRecord { - meta: KeyMetadata { - id, - created_at: now, - delete_after, - spec: spec_builder(algo, pub_key), - }, - private_key: vault, - }) - } - #[test] fn test_create_binding_key_success() { let algo = HpkeAlgorithm { diff --git a/keymanager/workload_service/integration_test.go b/keymanager/workload_service/integration_test.go index 89978b628..db9269c31 100644 --- a/keymanager/workload_service/integration_test.go +++ b/keymanager/workload_service/integration_test.go @@ -29,15 +29,14 @@ func TestIntegrationGenerateKeysEndToEnd(t *testing.T) { kpsSvc := kps.NewService(kpskcc.GenerateKEMKeypair) srv := NewServer(kpsSvc, &realWorkloadService{}) - reqBody, err := json.Marshal(GenerateKemRequest{ - Algorithm: KemAlgorithmDHKEMX25519HKDFSHA256, - KeyProtectionMechanism: KeyProtectionMechanismVM, - Lifespan: ProtoDuration{Seconds: 3600}, + reqBody, err := json.Marshal(GenerateKeyRequest{ + Algorithm: AlgorithmDetails{Type: "kem", Params: AlgorithmParams{KemID: KemAlgorithmDHKEMX25519HKDFSHA256}}, + Lifespan: ProtoDuration{Seconds: 3600}, }) if err != nil { t.Fatalf("failed to marshal request: %v", err) } - req := httptest.NewRequest(http.MethodPost, "/v1/keys:generate_kem", bytes.NewReader(reqBody)) + req := httptest.NewRequest(http.MethodPost, "/v1/keys:generate_key", bytes.NewReader(reqBody)) req.Header.Set("Content-Type", "application/json") w := httptest.NewRecorder() srv.Handler().ServeHTTP(w, req) @@ -46,7 +45,7 @@ func TestIntegrationGenerateKeysEndToEnd(t *testing.T) { t.Fatalf("expected status 200, got %d: %s", w.Code, w.Body.String()) } - var resp GenerateKemResponse + var resp GenerateKeyResponse if err := json.NewDecoder(w.Body).Decode(&resp); err != nil { t.Fatalf("failed to decode response: %v", err) } @@ -78,15 +77,14 @@ func TestIntegrationGenerateKeysUniqueMappings(t *testing.T) { // Generate two key sets. var kemUUIDs [2]uuid.UUID for i := 0; i < 2; i++ { - reqBody, err := json.Marshal(GenerateKemRequest{ - Algorithm: KemAlgorithmDHKEMX25519HKDFSHA256, - KeyProtectionMechanism: KeyProtectionMechanismVM, - Lifespan: ProtoDuration{Seconds: 3600}, + reqBody, err := json.Marshal(GenerateKeyRequest{ + Algorithm: AlgorithmDetails{Type: "kem", Params: AlgorithmParams{KemID: KemAlgorithmDHKEMX25519HKDFSHA256}}, + Lifespan: ProtoDuration{Seconds: 3600}, }) if err != nil { t.Fatalf("call %d: failed to marshal request: %v", i+1, err) } - req := httptest.NewRequest(http.MethodPost, "/v1/keys:generate_kem", bytes.NewReader(reqBody)) + req := httptest.NewRequest(http.MethodPost, "/v1/keys:generate_key", bytes.NewReader(reqBody)) req.Header.Set("Content-Type", "application/json") w := httptest.NewRecorder() srv.Handler().ServeHTTP(w, req) @@ -95,7 +93,7 @@ func TestIntegrationGenerateKeysUniqueMappings(t *testing.T) { t.Fatalf("call %d: expected status 200, got %d: %s", i+1, w.Code, w.Body.String()) } - var resp GenerateKemResponse + var resp GenerateKeyResponse if err := json.NewDecoder(w.Body).Decode(&resp); err != nil { t.Fatalf("call %d: failed to decode response: %v", i+1, err) } diff --git a/keymanager/workload_service/proto_enums.go b/keymanager/workload_service/proto_enums.go index 90a138d06..4e63673d7 100644 --- a/keymanager/workload_service/proto_enums.go +++ b/keymanager/workload_service/proto_enums.go @@ -57,64 +57,12 @@ func (k *KemAlgorithm) UnmarshalJSON(data []byte) error { return fmt.Errorf("unknown KemAlgorithm: %q", s) } -// KeyProtectionMechanism represents the requested key protection backend. -type KeyProtectionMechanism int32 - -const ( - // KeyProtectionMechanismDefault is the default but invalid value. - KeyProtectionMechanismDefault KeyProtectionMechanism = 1 - // KeyProtectionMechanismVM specifies that the key is protected by the VM. - KeyProtectionMechanismVM KeyProtectionMechanism = 2 -) - -var ( - keyProtectionMechanismToString = map[KeyProtectionMechanism]string{ - KeyProtectionMechanismDefault: "DEFAULT", - KeyProtectionMechanismVM: "KEY_PROTECTION_VM", - } - stringToKeyProtectionMechanism = map[string]KeyProtectionMechanism{ - "DEFAULT": KeyProtectionMechanismDefault, - "KEY_PROTECTION_VM": KeyProtectionMechanismVM, - } -) - -func (k KeyProtectionMechanism) String() string { - if s, ok := keyProtectionMechanismToString[k]; ok { - return s - } - return fmt.Sprintf("KEY_PROTECTION_MECHANISM_UNKNOWN(%d)", k) -} - -// MarshalJSON converts a KeyProtectionMechanism enum value to its JSON string representation. -func (k KeyProtectionMechanism) MarshalJSON() ([]byte, error) { - return json.Marshal(k.String()) -} - -// UnmarshalJSON parses a JSON string into a KeyProtectionMechanism enum value. -func (k *KeyProtectionMechanism) UnmarshalJSON(data []byte) error { - var s string - if err := json.Unmarshal(data, &s); err != nil { - return fmt.Errorf("KeyProtectionMechanism must be a string") - } - if v, ok := stringToKeyProtectionMechanism[s]; ok { - *k = v - return nil - } - return fmt.Errorf("unknown KeyProtectionMechanism: %q", s) -} - // Supported algorithms and mechanisms. var ( // SupportedKemAlgorithms is the source of truth for supported algorithms. SupportedKemAlgorithms = []KemAlgorithm{ KemAlgorithmDHKEMX25519HKDFSHA256, } - - // SupportedKeyProtectionMechanisms is the source of truth for supported mechanisms. - SupportedKeyProtectionMechanisms = []KeyProtectionMechanism{ - KeyProtectionMechanismDefault, - KeyProtectionMechanismVM, - } ) // IsSupported returns true if the KEM algorithm is supported. @@ -127,17 +75,7 @@ func (k KemAlgorithm) IsSupported() bool { return false } -// IsSupported returns true if the key protection mechanism is supported. -func (k KeyProtectionMechanism) IsSupported() bool { - for _, supported := range SupportedKeyProtectionMechanisms { - if k == supported { - return true - } - } - return false -} - -// SupportedKemAlgorithmsString returns a comma-separated list of supported KEM keymanager. +// SupportedKemAlgorithmsString returns a comma-separated list of supported KEM algorithms. func SupportedKemAlgorithmsString() string { var names []string for _, k := range SupportedKemAlgorithms { diff --git a/keymanager/workload_service/server.go b/keymanager/workload_service/server.go index ae976e29c..2f66a0532 100644 --- a/keymanager/workload_service/server.go +++ b/keymanager/workload_service/server.go @@ -68,15 +68,14 @@ func (d ProtoDuration) MarshalJSON() ([]byte, error) { return json.Marshal(d.Seconds) } -// GenerateKemRequest is the JSON body for POST /v1/keys:generate_kem. -type GenerateKemRequest struct { - Algorithm KemAlgorithm `json:"algorithm"` - KeyProtectionMechanism KeyProtectionMechanism `json:"key_protection_mechanism"` - Lifespan ProtoDuration `json:"lifespan"` +// GenerateKeyRequest is the JSON body for POST /v1/keys:generate_key. +type GenerateKeyRequest struct { + Algorithm AlgorithmDetails `json:"algorithm"` + Lifespan ProtoDuration `json:"lifespan"` } -// GenerateKemResponse is returned by POST /v1/keys:generate_kem. -type GenerateKemResponse struct { +// GenerateKeyResponse is returned by POST /v1/keys:generate_key. +type GenerateKeyResponse struct { KeyHandle KeyHandle `json:"key_handle"` } @@ -129,7 +128,7 @@ func NewServer(keyProtectionService KeyProtectionService, workloadService Worklo } mux := http.NewServeMux() - mux.HandleFunc("POST /v1/keys:generate_kem", s.handleGenerateKem) + mux.HandleFunc("POST /v1/keys:generate_key", s.handleGenerateKey) mux.HandleFunc("GET /v1/capabilities", s.handleGetCapabilities) s.httpServer = &http.Server{Handler: mux} @@ -166,34 +165,37 @@ func (s *Server) LookupBindingUUID(kemUUID uuid.UUID) (uuid.UUID, bool) { return id, ok } -func (s *Server) handleGenerateKem(w http.ResponseWriter, r *http.Request) { - var req GenerateKemRequest +func (s *Server) handleGenerateKey(w http.ResponseWriter, r *http.Request) { + var req GenerateKeyRequest if err := json.NewDecoder(r.Body).Decode(&req); err != nil { writeError(w, fmt.Sprintf("invalid request body: %v", err), http.StatusBadRequest) return } - // Validate algorithm. - if !req.Algorithm.IsSupported() { - writeError(w, fmt.Sprintf("unsupported algorithm: %s. Supported algorithms: %s", req.Algorithm, SupportedKemAlgorithmsString()), http.StatusBadRequest) + // Validate lifespan is positive. + if req.Lifespan.Seconds == 0 { + writeError(w, "lifespan must be greater than 0s", http.StatusBadRequest) return } - // Validate keyProtectionMechanism. - if !req.KeyProtectionMechanism.IsSupported() { - writeError(w, fmt.Sprintf("unsupported keyProtectionMechanism: %s", req.KeyProtectionMechanism), http.StatusBadRequest) - return + switch req.Algorithm.Type { + case "kem": + s.generateKEMKey(w, req) + default: + writeError(w, fmt.Sprintf("unsupported algorithm type: %q. Only 'kem' is supported.", req.Algorithm.Type), http.StatusBadRequest) } +} - // Validate lifespan is positive. - if req.Lifespan.Seconds == 0 { - writeError(w, "lifespan must be greater than 0s", http.StatusBadRequest) +func (s *Server) generateKEMKey(w http.ResponseWriter, req GenerateKeyRequest) { + // Validate algorithm. + if !req.Algorithm.Params.KemID.IsSupported() { + writeError(w, fmt.Sprintf("unsupported algorithm: %s. Supported algorithms: %s", req.Algorithm.Params.KemID, SupportedKemAlgorithmsString()), http.StatusBadRequest) return } // Construct the full HPKE algorithm suite based on the requested KEM. // We currently only support one suite. - algo, err := req.Algorithm.ToHpkeAlgorithm() + algo, err := req.Algorithm.Params.KemID.ToHpkeAlgorithm() if err != nil { writeError(w, err.Error(), http.StatusBadRequest) return @@ -219,7 +221,7 @@ func (s *Server) handleGenerateKem(w http.ResponseWriter, r *http.Request) { s.mu.Unlock() // Step 4: Return KEM UUID to workload. - resp := GenerateKemResponse{ + resp := GenerateKeyResponse{ KeyHandle: KeyHandle{Handle: kemUUID.String()}, } writeJSON(w, resp, http.StatusOK) diff --git a/keymanager/workload_service/server_test.go b/keymanager/workload_service/server_test.go index f6ff7db3e..69edeed3b 100644 --- a/keymanager/workload_service/server_test.go +++ b/keymanager/workload_service/server_test.go @@ -50,15 +50,19 @@ func (m *mockKeyProtectionService) GenerateKEMKeypair(_ *keymanager.HpkeAlgorith } func validGenerateBody() []byte { - body, _ := json.Marshal(GenerateKemRequest{ - Algorithm: KemAlgorithmDHKEMX25519HKDFSHA256, - KeyProtectionMechanism: KeyProtectionMechanismVM, - Lifespan: ProtoDuration{Seconds: 3600}, + body, _ := json.Marshal(GenerateKeyRequest{ + Algorithm: AlgorithmDetails{ + Type: "kem", + Params: AlgorithmParams{ + KemID: KemAlgorithmDHKEMX25519HKDFSHA256, + }, + }, + Lifespan: ProtoDuration{Seconds: 3600}, }) return body } -func TestHandleGenerateKemSuccess(t *testing.T) { +func TestHandleGenerateKeySuccess(t *testing.T) { bindingUUID := uuid.New() kemUUID := uuid.New() bindingPubKey := make([]byte, 32) @@ -76,7 +80,7 @@ func TestHandleGenerateKemSuccess(t *testing.T) { &mockWorkloadService{uuid: bindingUUID, pubKey: bindingPubKey}, ) - req := httptest.NewRequest(http.MethodPost, "/v1/keys:generate_kem", bytes.NewReader(validGenerateBody())) + req := httptest.NewRequest(http.MethodPost, "/v1/keys:generate_key", bytes.NewReader(validGenerateBody())) req.Header.Set("Content-Type", "application/json") w := httptest.NewRecorder() srv.Handler().ServeHTTP(w, req) @@ -85,7 +89,7 @@ func TestHandleGenerateKemSuccess(t *testing.T) { t.Fatalf("expected status 200, got %d: %s", w.Code, w.Body.String()) } - var resp GenerateKemResponse + var resp GenerateKeyResponse if err := json.NewDecoder(w.Body).Decode(&resp); err != nil { t.Fatalf("failed to decode response: %v", err) } @@ -118,13 +122,13 @@ func TestHandleGenerateKemSuccess(t *testing.T) { } } -func TestHandleGenerateKemInvalidMethod(t *testing.T) { +func TestHandleGenerateKeyInvalidMethod(t *testing.T) { srv := newTestServer(t, &mockKeyProtectionService{pubKey: make([]byte, 32)}, &mockWorkloadService{pubKey: make([]byte, 32)}, ) - req := httptest.NewRequest(http.MethodGet, "/v1/keys:generate_kem", nil) + req := httptest.NewRequest(http.MethodGet, "/v1/keys:generate_key", nil) w := httptest.NewRecorder() srv.Handler().ServeHTTP(w, req) @@ -133,7 +137,7 @@ func TestHandleGenerateKemInvalidMethod(t *testing.T) { } } -func TestHandleGenerateKemBadRequest(t *testing.T) { +func TestHandleGenerateKeyBadRequest(t *testing.T) { srv := newTestServer(t, &mockKeyProtectionService{uuid: uuid.New(), pubKey: make([]byte, 32)}, &mockWorkloadService{uuid: uuid.New(), pubKey: make([]byte, 32)}, @@ -141,30 +145,30 @@ func TestHandleGenerateKemBadRequest(t *testing.T) { tests := []struct { name string - body GenerateKemRequest + body GenerateKeyRequest }{ { - name: "unsupported algorithm", - body: GenerateKemRequest{Algorithm: KemAlgorithmUnspecified, KeyProtectionMechanism: KeyProtectionMechanismVM, Lifespan: ProtoDuration{Seconds: 3600}}, + name: "unsupported algorithm type", + body: GenerateKeyRequest{Algorithm: AlgorithmDetails{Type: "mac", Params: AlgorithmParams{KemID: KemAlgorithmDHKEMX25519HKDFSHA256}}, Lifespan: ProtoDuration{Seconds: 3600}}, }, { - name: "unsupported key protection mechanism", - body: GenerateKemRequest{Algorithm: KemAlgorithmDHKEMX25519HKDFSHA256, KeyProtectionMechanism: KeyProtectionMechanism(99), Lifespan: ProtoDuration{Seconds: 3600}}, + name: "unsupported algorithm", + body: GenerateKeyRequest{Algorithm: AlgorithmDetails{Type: "kem", Params: AlgorithmParams{KemID: KemAlgorithmUnspecified}}, Lifespan: ProtoDuration{Seconds: 3600}}, }, { name: "zero lifespan", - body: GenerateKemRequest{Algorithm: KemAlgorithmDHKEMX25519HKDFSHA256, KeyProtectionMechanism: KeyProtectionMechanismVM, Lifespan: ProtoDuration{Seconds: 0}}, + body: GenerateKeyRequest{Algorithm: AlgorithmDetails{Type: "kem", Params: AlgorithmParams{KemID: KemAlgorithmDHKEMX25519HKDFSHA256}}, Lifespan: ProtoDuration{Seconds: 0}}, }, { - name: "missing algorithm (defaults to 0)", - body: GenerateKemRequest{KeyProtectionMechanism: KeyProtectionMechanismVM, Lifespan: ProtoDuration{Seconds: 3600}}, + name: "missing algorithm (defaults to 0, type empty)", + body: GenerateKeyRequest{Lifespan: ProtoDuration{Seconds: 3600}}, }, } for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { body, _ := json.Marshal(tc.body) - req := httptest.NewRequest(http.MethodPost, "/v1/keys:generate_kem", bytes.NewReader(body)) + req := httptest.NewRequest(http.MethodPost, "/v1/keys:generate_key", bytes.NewReader(body)) req.Header.Set("Content-Type", "application/json") w := httptest.NewRecorder() srv.Handler().ServeHTTP(w, req) @@ -187,7 +191,7 @@ func TestHandleGenerateKemBadRequest(t *testing.T) { } } -func TestHandleGenerateKemBadJSON(t *testing.T) { +func TestHandleGenerateKeyBadJSON(t *testing.T) { srv := newTestServer(t, &mockKeyProtectionService{pubKey: make([]byte, 32)}, &mockWorkloadService{pubKey: make([]byte, 32)}, @@ -198,14 +202,14 @@ func TestHandleGenerateKemBadJSON(t *testing.T) { body string }{ {"not json", "not json"}, - {"lifespan as string", `{"algorithm":1,"key_protection_mechanism":2,"lifespan":"3600"}`}, - {"lifespan as string with suffix", `{"algorithm":1,"key_protection_mechanism":2,"lifespan":"3600s"}`}, - {"lifespan negative", `{"algorithm":1,"key_protection_mechanism":2,"lifespan":-1}`}, + {"lifespan as string", `{"algorithm":1,"lifespan":"3600"}`}, + {"lifespan as string with suffix", `{"algorithm":1,"lifespan":"3600s"}`}, + {"lifespan negative", `{"algorithm":1,"lifespan":-1}`}, } for _, tc := range badBodies { t.Run(tc.name, func(t *testing.T) { - req := httptest.NewRequest(http.MethodPost, "/v1/keys:generate_kem", bytes.NewReader([]byte(tc.body))) + req := httptest.NewRequest(http.MethodPost, "/v1/keys:generate_key", bytes.NewReader([]byte(tc.body))) req.Header.Set("Content-Type", "application/json") w := httptest.NewRecorder() srv.Handler().ServeHTTP(w, req) @@ -217,13 +221,13 @@ func TestHandleGenerateKemBadJSON(t *testing.T) { } } -func TestHandleGenerateKemBindingGenError(t *testing.T) { +func TestHandleGenerateKeyBindingGenError(t *testing.T) { srv := newTestServer(t, &mockKeyProtectionService{pubKey: make([]byte, 32)}, &mockWorkloadService{err: fmt.Errorf("binding FFI error")}, ) - req := httptest.NewRequest(http.MethodPost, "/v1/keys:generate_kem", bytes.NewReader(validGenerateBody())) + req := httptest.NewRequest(http.MethodPost, "/v1/keys:generate_key", bytes.NewReader(validGenerateBody())) req.Header.Set("Content-Type", "application/json") w := httptest.NewRecorder() srv.Handler().ServeHTTP(w, req) @@ -233,7 +237,7 @@ func TestHandleGenerateKemBindingGenError(t *testing.T) { } } -func TestHandleGenerateKemFlexibleLifespan(t *testing.T) { +func TestHandleGenerateKeyFlexibleLifespan(t *testing.T) { srv := newTestServer(t, &mockKeyProtectionService{uuid: uuid.New(), pubKey: make([]byte, 32)}, &mockWorkloadService{uuid: uuid.New(), pubKey: make([]byte, 32)}, @@ -246,24 +250,24 @@ func TestHandleGenerateKemFlexibleLifespan(t *testing.T) { }{ { name: "integer seconds", - body: `{"algorithm":"DHKEM_X25519_HKDF_SHA256","key_protection_mechanism":"KEY_PROTECTION_VM","lifespan":3600}`, + body: `{"algorithm":{"type":"kem","params":{"kem_id":"DHKEM_X25519_HKDF_SHA256"}},"lifespan":3600}`, expected: 3600, }, { name: "float seconds", - body: `{"algorithm":"DHKEM_X25519_HKDF_SHA256","key_protection_mechanism":"KEY_PROTECTION_VM","lifespan":1.5}`, + body: `{"algorithm":{"type":"kem","params":{"kem_id":"DHKEM_X25519_HKDF_SHA256"}},"lifespan":1.5}`, expected: 1, // Truncated to 1 }, { name: "float seconds round down", - body: `{"algorithm":"DHKEM_X25519_HKDF_SHA256","key_protection_mechanism":"KEY_PROTECTION_VM","lifespan":3600.9}`, + body: `{"algorithm":{"type":"kem","params":{"kem_id":"DHKEM_X25519_HKDF_SHA256"}},"lifespan":3600.9}`, expected: 3600, }, } for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { - req := httptest.NewRequest(http.MethodPost, "/v1/keys:generate_kem", bytes.NewReader([]byte(tc.body))) + req := httptest.NewRequest(http.MethodPost, "/v1/keys:generate_key", bytes.NewReader([]byte(tc.body))) req.Header.Set("Content-Type", "application/json") w := httptest.NewRecorder() srv.Handler().ServeHTTP(w, req) @@ -275,13 +279,13 @@ func TestHandleGenerateKemFlexibleLifespan(t *testing.T) { } } -func TestHandleGenerateKemKEMGenError(t *testing.T) { +func TestHandleGenerateKeyKEMGenError(t *testing.T) { srv := newTestServer(t, &mockKeyProtectionService{err: fmt.Errorf("KEM FFI error")}, &mockWorkloadService{uuid: uuid.New(), pubKey: make([]byte, 32)}, ) - req := httptest.NewRequest(http.MethodPost, "/v1/keys:generate_kem", bytes.NewReader(validGenerateBody())) + req := httptest.NewRequest(http.MethodPost, "/v1/keys:generate_key", bytes.NewReader(validGenerateBody())) req.Header.Set("Content-Type", "application/json") w := httptest.NewRecorder() srv.Handler().ServeHTTP(w, req) @@ -291,7 +295,7 @@ func TestHandleGenerateKemKEMGenError(t *testing.T) { } } -func TestHandleGenerateKemMapUniqueness(t *testing.T) { +func TestHandleGenerateKeyMapUniqueness(t *testing.T) { bindingPubKey := make([]byte, 32) bindingUUID1 := uuid.New() @@ -311,7 +315,7 @@ func TestHandleGenerateKemMapUniqueness(t *testing.T) { kemGen.uuid = kemUUID1 kemGen.pubKey = make([]byte, 32) - req := httptest.NewRequest(http.MethodPost, "/v1/keys:generate_kem", bytes.NewReader(validGenerateBody())) + req := httptest.NewRequest(http.MethodPost, "/v1/keys:generate_key", bytes.NewReader(validGenerateBody())) req.Header.Set("Content-Type", "application/json") w := httptest.NewRecorder() srv.Handler().ServeHTTP(w, req) @@ -324,7 +328,7 @@ func TestHandleGenerateKemMapUniqueness(t *testing.T) { bindingGen.uuid = bindingUUID2 kemGen.uuid = kemUUID2 - req = httptest.NewRequest(http.MethodPost, "/v1/keys:generate_kem", bytes.NewReader(validGenerateBody())) + req = httptest.NewRequest(http.MethodPost, "/v1/keys:generate_key", bytes.NewReader(validGenerateBody())) req.Header.Set("Content-Type", "application/json") w = httptest.NewRecorder() srv.Handler().ServeHTTP(w, req)