Skip to content

Commit dab941a

Browse files
committed
[keymanager] GenerateKey API - incorporate signature change
Key changes: - Renamed endpoint from /v1/keys:generate_kem to /v1/keys:generate_key. - Restructured `GenerateKeyRequest` to use a nested `Algorithm` definition containing `Type` and an algorithm-specific `Params` object with `kem_id`. - Added support for `KEY_PROTECTION_VM_EMULATED` in the KeyProtectionMechanism enum and established this as the default and only supported mechanism for Vanguard so far. - Validated lifecycle configurations and parsed `Algorithm` appropriately according to updated schemas. - Updated associated unit and integration tests (server_test.go, integration_test.go) to use the new endpoints and the new request signature.
1 parent fbcd74a commit dab941a

File tree

4 files changed

+82
-60
lines changed

4 files changed

+82
-60
lines changed

keymanager/workload_service/integration_test.go

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,15 +29,15 @@ func TestIntegrationGenerateKeysEndToEnd(t *testing.T) {
2929
kpsSvc := kps.NewService(kpskcc.GenerateKEMKeypair)
3030
srv := NewServer(kpsSvc, &realWorkloadService{})
3131

32-
reqBody, err := json.Marshal(GenerateKemRequest{
33-
Algorithm: KemAlgorithmDHKEMX25519HKDFSHA256,
34-
KeyProtectionMechanism: KeyProtectionMechanismVM,
32+
reqBody, err := json.Marshal(GenerateKeyRequest{
33+
Algorithm: AlgorithmDetails{Type: "kem", Params: AlgorithmParams{KemID: KemAlgorithmDHKEMX25519HKDFSHA256}},
34+
KeyProtectionMechanism: KeyProtectionMechanismVMEmulated,
3535
Lifespan: ProtoDuration{Seconds: 3600},
3636
})
3737
if err != nil {
3838
t.Fatalf("failed to marshal request: %v", err)
3939
}
40-
req := httptest.NewRequest(http.MethodPost, "/v1/keys:generate_kem", bytes.NewReader(reqBody))
40+
req := httptest.NewRequest(http.MethodPost, "/v1/keys:generate_key", bytes.NewReader(reqBody))
4141
req.Header.Set("Content-Type", "application/json")
4242
w := httptest.NewRecorder()
4343
srv.Handler().ServeHTTP(w, req)
@@ -46,7 +46,7 @@ func TestIntegrationGenerateKeysEndToEnd(t *testing.T) {
4646
t.Fatalf("expected status 200, got %d: %s", w.Code, w.Body.String())
4747
}
4848

49-
var resp GenerateKemResponse
49+
var resp GenerateKeyResponse
5050
if err := json.NewDecoder(w.Body).Decode(&resp); err != nil {
5151
t.Fatalf("failed to decode response: %v", err)
5252
}
@@ -78,15 +78,15 @@ func TestIntegrationGenerateKeysUniqueMappings(t *testing.T) {
7878
// Generate two key sets.
7979
var kemUUIDs [2]uuid.UUID
8080
for i := 0; i < 2; i++ {
81-
reqBody, err := json.Marshal(GenerateKemRequest{
82-
Algorithm: KemAlgorithmDHKEMX25519HKDFSHA256,
83-
KeyProtectionMechanism: KeyProtectionMechanismVM,
81+
reqBody, err := json.Marshal(GenerateKeyRequest{
82+
Algorithm: AlgorithmDetails{Type: "kem", Params: AlgorithmParams{KemID: KemAlgorithmDHKEMX25519HKDFSHA256}},
83+
KeyProtectionMechanism: KeyProtectionMechanismVMEmulated,
8484
Lifespan: ProtoDuration{Seconds: 3600},
8585
})
8686
if err != nil {
8787
t.Fatalf("call %d: failed to marshal request: %v", i+1, err)
8888
}
89-
req := httptest.NewRequest(http.MethodPost, "/v1/keys:generate_kem", bytes.NewReader(reqBody))
89+
req := httptest.NewRequest(http.MethodPost, "/v1/keys:generate_key", bytes.NewReader(reqBody))
9090
req.Header.Set("Content-Type", "application/json")
9191
w := httptest.NewRecorder()
9292
srv.Handler().ServeHTTP(w, req)
@@ -95,7 +95,7 @@ func TestIntegrationGenerateKeysUniqueMappings(t *testing.T) {
9595
t.Fatalf("call %d: expected status 200, got %d: %s", i+1, w.Code, w.Body.String())
9696
}
9797

98-
var resp GenerateKemResponse
98+
var resp GenerateKeyResponse
9999
if err := json.NewDecoder(w.Body).Decode(&resp); err != nil {
100100
t.Fatalf("call %d: failed to decode response: %v", i+1, err)
101101
}

keymanager/workload_service/proto_enums.go

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -61,20 +61,26 @@ func (k *KemAlgorithm) UnmarshalJSON(data []byte) error {
6161
type KeyProtectionMechanism int32
6262

6363
const (
64+
KeyProtectionMechanismUnspecified KeyProtectionMechanism = 0
6465
// KeyProtectionMechanismDefault is the default but invalid value.
6566
KeyProtectionMechanismDefault KeyProtectionMechanism = 1
6667
// KeyProtectionMechanismVM specifies that the key is protected by the VM.
67-
KeyProtectionMechanismVM KeyProtectionMechanism = 2
68+
KeyProtectionMechanismVM KeyProtectionMechanism = 2
69+
KeyProtectionMechanismVMEmulated KeyProtectionMechanism = 3
6870
)
6971

7072
var (
7173
keyProtectionMechanismToString = map[KeyProtectionMechanism]string{
72-
KeyProtectionMechanismDefault: "DEFAULT",
73-
KeyProtectionMechanismVM: "KEY_PROTECTION_VM",
74+
KeyProtectionMechanismUnspecified: "KEY_PROTECTION_UNSPECIFIED",
75+
KeyProtectionMechanismDefault: "DEFAULT",
76+
KeyProtectionMechanismVM: "KEY_PROTECTION_VM",
77+
KeyProtectionMechanismVMEmulated: "KEY_PROTECTION_VM_EMULATED",
7478
}
7579
stringToKeyProtectionMechanism = map[string]KeyProtectionMechanism{
76-
"DEFAULT": KeyProtectionMechanismDefault,
77-
"KEY_PROTECTION_VM": KeyProtectionMechanismVM,
80+
"KEY_PROTECTION_UNSPECIFIED": KeyProtectionMechanismUnspecified,
81+
"DEFAULT": KeyProtectionMechanismDefault,
82+
"KEY_PROTECTION_VM": KeyProtectionMechanismVM,
83+
"KEY_PROTECTION_VM_EMULATED": KeyProtectionMechanismVMEmulated,
7884
}
7985
)
8086

@@ -112,8 +118,7 @@ var (
112118

113119
// SupportedKeyProtectionMechanisms is the source of truth for supported mechanisms.
114120
SupportedKeyProtectionMechanisms = []KeyProtectionMechanism{
115-
KeyProtectionMechanismDefault,
116-
KeyProtectionMechanismVM,
121+
KeyProtectionMechanismVMEmulated,
117122
}
118123
)
119124

keymanager/workload_service/server.go

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -68,15 +68,15 @@ func (d ProtoDuration) MarshalJSON() ([]byte, error) {
6868
return json.Marshal(d.Seconds)
6969
}
7070

71-
// GenerateKemRequest is the JSON body for POST /v1/keys:generate_kem.
72-
type GenerateKemRequest struct {
73-
Algorithm KemAlgorithm `json:"algorithm"`
74-
KeyProtectionMechanism KeyProtectionMechanism `json:"key_protection_mechanism"`
71+
// GenerateKeyRequest is the JSON body for POST /v1/keys:generate_key.
72+
type GenerateKeyRequest struct {
73+
Algorithm AlgorithmDetails `json:"algorithm"`
74+
KeyProtectionMechanism KeyProtectionMechanism `json:"key_protection_mechanism,omitempty"`
7575
Lifespan ProtoDuration `json:"lifespan"`
7676
}
7777

78-
// GenerateKemResponse is returned by POST /v1/keys:generate_kem.
79-
type GenerateKemResponse struct {
78+
// GenerateKeyResponse is returned by POST /v1/keys:generate_key.
79+
type GenerateKeyResponse struct {
8080
KeyHandle KeyHandle `json:"key_handle"`
8181
}
8282

@@ -129,7 +129,7 @@ func NewServer(keyProtectionService KeyProtectionService, workloadService Worklo
129129
}
130130

131131
mux := http.NewServeMux()
132-
mux.HandleFunc("POST /v1/keys:generate_kem", s.handleGenerateKem)
132+
mux.HandleFunc("POST /v1/keys:generate_key", s.handleGenerateKey)
133133
mux.HandleFunc("GET /v1/capabilities", s.handleGetCapabilities)
134134

135135
s.httpServer = &http.Server{Handler: mux}
@@ -166,20 +166,28 @@ func (s *Server) LookupBindingUUID(kemUUID uuid.UUID) (uuid.UUID, bool) {
166166
return id, ok
167167
}
168168

169-
func (s *Server) handleGenerateKem(w http.ResponseWriter, r *http.Request) {
170-
var req GenerateKemRequest
169+
func (s *Server) handleGenerateKey(w http.ResponseWriter, r *http.Request) {
170+
var req GenerateKeyRequest
171171
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
172172
writeError(w, fmt.Sprintf("invalid request body: %v", err), http.StatusBadRequest)
173173
return
174174
}
175175

176+
if req.Algorithm.Type != "kem" {
177+
writeError(w, fmt.Sprintf("unsupported algorithm type: %q. Only 'kem' is supported.", req.Algorithm.Type), http.StatusBadRequest)
178+
return
179+
}
180+
176181
// Validate algorithm.
177-
if !req.Algorithm.IsSupported() {
178-
writeError(w, fmt.Sprintf("unsupported algorithm: %s. Supported algorithms: %s", req.Algorithm, SupportedKemAlgorithmsString()), http.StatusBadRequest)
182+
if !req.Algorithm.Params.KemID.IsSupported() {
183+
writeError(w, fmt.Sprintf("unsupported algorithm: %s. Supported algorithms: %s", req.Algorithm.Params.KemID, SupportedKemAlgorithmsString()), http.StatusBadRequest)
179184
return
180185
}
181186

182187
// Validate keyProtectionMechanism.
188+
if req.KeyProtectionMechanism == KeyProtectionMechanismUnspecified {
189+
req.KeyProtectionMechanism = KeyProtectionMechanismVMEmulated
190+
}
183191
if !req.KeyProtectionMechanism.IsSupported() {
184192
writeError(w, fmt.Sprintf("unsupported keyProtectionMechanism: %s", req.KeyProtectionMechanism), http.StatusBadRequest)
185193
return
@@ -193,7 +201,7 @@ func (s *Server) handleGenerateKem(w http.ResponseWriter, r *http.Request) {
193201

194202
// Construct the full HPKE algorithm suite based on the requested KEM.
195203
// We currently only support one suite.
196-
algo, err := req.Algorithm.ToHpkeAlgorithm()
204+
algo, err := req.Algorithm.Params.KemID.ToHpkeAlgorithm()
197205
if err != nil {
198206
writeError(w, err.Error(), http.StatusBadRequest)
199207
return
@@ -219,7 +227,7 @@ func (s *Server) handleGenerateKem(w http.ResponseWriter, r *http.Request) {
219227
s.mu.Unlock()
220228

221229
// Step 4: Return KEM UUID to workload.
222-
resp := GenerateKemResponse{
230+
resp := GenerateKeyResponse{
223231
KeyHandle: KeyHandle{Handle: kemUUID.String()},
224232
}
225233
writeJSON(w, resp, http.StatusOK)

0 commit comments

Comments
 (0)