1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
24 */
25
26 /**
27 * \file KMSAgent.cpp
28 */
29
30 #ifdef WIN32
31 #define _WIN32_WINNT 0x0400
32 #include <windows.h>
33 #include <process.h>
34 #endif
35
36 #include <stdlib.h>
37
38 #include "KMSClientProfile.h"
39
40 #include "KMS_AgentStub.h"
41 #include "KMS_DiscoveryStub.h"
42
43 #include "KMSClientProfileImpl.h"
44 #include "KMSAgent.h"
45 #include "KMSAuditLogger.h"
46 #include "KMSAgentSoapUtilities.h"
47 #include "KMSAgentStringUtilities.h"
48 #include "KMSAgentPKICommon.h"
49 #include "KMSAgentLoadBalancer.h"
50
51 #include "KMSAgentWebServiceNamespaces.h"
52 #include "k_setupssl.h"
53
54 #include "ApplianceParameters.h"
55
56 #include "AutoMutex.h"
57 #include "KMSAgentKeyCallout.h"
58
59 #include "KMSAgentLoadBalancer.h"
60 #include "KMSAgentDataUnitCache.h"
61
62 #ifdef K_SOLARIS_PLATFORM
63 #include "KMSAgentStorage.h"
64 #endif
65
66 #include "ClientSoapFaultCodes.h"
67
68 #ifdef METAWARE
69 #include "debug.h"
70 #include "sizet.h"
71 typedef unsigned char uint8_t;
72 typedef unsigned short uint16_t;
73 typedef unsigned int uint32_t;
74 typedef unsigned long long uint64_t;
75 #endif
76
77 #include "KMSAgentAESKeyWrap.h"
78 #include "KMSAgentKnownAnswerTests.h"
79
80 #if defined(METAWARE) && defined(DEBUG_RETURNS)
81 extern "C" void ecpt_trace_msg (ECPT_TRACE_ENTRY*, char*, ...);
82
83 #define RETURN(a) { ecpt_trace_msg( trace,"(returned=%x)",(a)); return(a); }
84
85 #else
86 #define RETURN(a) return(a)
87 #endif
88
89 /* KMS_AGENT_VERSION_STRING gets passed in via compilation flags */
90 extern "C" const char KMSAgent_Version[KMS_MAX_VERSION_LENGTH + 1] = KMS_AGENT_VERSION_STRING;
91
92
93 /* The following enum and structs are used for QueryParameters in
94 * ListKeyGroup. Since they are only used in implementation code,
95 * so they are not in the header file in order to hide these details
96 */
97
98
99 /*---------------------------Start Query Parameters Declartion -------- */
100
101 #define KMS_MAX_AGENT_FILTER_PARAMETERS 10
102
103 enum KMSAgent_SortOrder
104 {
105 SORT_ORDER_ASCENDING = 0,
106 SORT_ORDER_DESCENDING
107 };
108
109 enum KMSAgent_FilterOperator
110 {
111 FILTER_OPERATOR_EQUAL = 0,
112 FILTER_OPERATOR_NOT_EQUAL,
113 FILTER_OPERATOR_GREATER_THAN,
114 FILTER_OPERATOR_LESS_THAN,
115 FILTER_OPERATOR_GREATER_THAN_OR_EQUAL,
116 FILTER_OPERATOR_LESS_THAN_OR_EQUAL,
117 FILTER_OPERATOR_STARTS_WITH
118 };
119
120 struct KMSAgent_FilterParameters
121 {
122 utf8char m_wsFieldName[KMS_MAX_FIELD_NAME + 1];
123 enum KMSAgent_FilterOperator m_eFilterOperator;
124 utf8char m_wsFieldValue[KMS_MAX_FIELD_VALUE + 1];
125 };
126
127 struct KMSAgent_QueryParameters
128 {
129 utf8char m_wsSortFieldName[KMS_MAX_FIELD_NAME + 1];
130 enum KMSAgent_SortOrder m_eSortOrder;
131
132 struct KMSAgent_FilterParameters m_aFilterParameters[KMS_MAX_AGENT_FILTER_PARAMETERS];
133 int m_iSizeFilterParameters;
134
135 utf8char m_wsPreviousPageLastIDValue[KMS_MAX_ID + 1];
136 utf8char m_wsPreviousPageLastSortFieldValue[KMS_MAX_FIELD_VALUE + 1];
137 };
138
139 /*---------------------------End Of Query Parameters Declaration -------- */
140
141 #ifdef METAWARE
142 int CAgentLoadBalancer::FailOver (int i_iFailedApplianceIndex,
143 struct soap *i_pstSoap);
144 #endif
145
KMSAgent_GetVersion()146 extern const char * KMSAgent_GetVersion ()
147 {
148 return (KMSAgent_Version);
149 }
150
CopyQueryParametersFromRequest(struct soap * i_pstSoap,int i_iPageSize,struct KMS_Agent::KMS_Agent__QueryParameters * i_pQueryParameters,struct KMSAgent_QueryParameters * i_pSourceQueryParameters)151 static bool CopyQueryParametersFromRequest
152 (
153 struct soap *i_pstSoap,
154 int i_iPageSize,
155 struct KMS_Agent::KMS_Agent__QueryParameters *i_pQueryParameters,
156 struct KMSAgent_QueryParameters *i_pSourceQueryParameters
157 )
158 {
159
160 // set page size
161 i_pQueryParameters->NextPageSize = i_iPageSize;
162
163 // copy sort field name
164 i_pQueryParameters->SortFieldName = (char *)
165 soap_malloc(i_pstSoap,
166 sizeof (i_pSourceQueryParameters->m_wsSortFieldName));
167 if (i_pQueryParameters->SortFieldName == NULL)
168 {
169 return (false);
170 }
171 strncpy(i_pQueryParameters->SortFieldName,
172 i_pSourceQueryParameters->m_wsSortFieldName,
173 sizeof (i_pSourceQueryParameters->m_wsSortFieldName));
174 i_pQueryParameters->SortFieldName[sizeof (i_pSourceQueryParameters->m_wsSortFieldName)-1] = 0;
175
176 // sort order
177 i_pQueryParameters->SortOrder =
178 (enum KMS_Agent::KMS_Agent__SortOrder)i_pSourceQueryParameters->m_eSortOrder;
179
180 // copy filter parameters
181 i_pQueryParameters->FilterParameters.__size =
182 i_pSourceQueryParameters->m_iSizeFilterParameters;
183
184 if (i_pQueryParameters->FilterParameters.__size > 0)
185 {
186 i_pQueryParameters->
187 FilterParameters.__ptr =
188 (struct KMS_Agent::KMS_Agent__FilterParameters *)soap_malloc
189 (i_pstSoap,
190 sizeof (KMS_Agent::KMS_Agent__FilterParameters) *
191 i_pQueryParameters->FilterParameters.__size);
192
193 if (i_pQueryParameters->FilterParameters.__ptr == NULL)
194 {
195 return (false);
196 }
197 }
198 else
199 {
200 i_pQueryParameters->FilterParameters.__ptr = NULL;
201 }
202
203 for (int i = 0; i < i_pSourceQueryParameters->m_iSizeFilterParameters; i++)
204 {
205 struct KMS_Agent::KMS_Agent__FilterParameters *pParameters;
206
207 pParameters = &(i_pQueryParameters->FilterParameters.__ptr[i]);
208
209 // copy field name
210 pParameters->FieldName = (
211 utf8cstr) soap_malloc(i_pstSoap,
212 sizeof (i_pSourceQueryParameters->
213 m_aFilterParameters[i].m_wsFieldName));
214 if (pParameters->FieldName == NULL)
215 {
216 return (false);
217 }
218
219 strncpy(pParameters->FieldName,
220 i_pSourceQueryParameters->m_aFilterParameters[i].m_wsFieldName,
221 sizeof (i_pSourceQueryParameters->
222 m_aFilterParameters[i].m_wsFieldName));
223 pParameters->FieldName[sizeof (i_pSourceQueryParameters->
224 m_aFilterParameters[i].m_wsFieldName)-1] = '\0';
225
226 // copy field value
227 pParameters->FieldValue =
228 (utf8cstr) soap_malloc
229 (i_pstSoap,
230 sizeof (i_pSourceQueryParameters->m_aFilterParameters[i].m_wsFieldValue));
231 if (pParameters->FieldValue == NULL)
232 {
233 return (false);
234 }
235
236 strncpy(pParameters->FieldValue,
237 i_pSourceQueryParameters->m_aFilterParameters[i].m_wsFieldValue,
238 sizeof (i_pSourceQueryParameters->m_aFilterParameters[i].m_wsFieldValue));
239 pParameters->FieldValue[sizeof (i_pSourceQueryParameters->m_aFilterParameters[i].m_wsFieldValue)-1] = '\0';
240
241 // copy FilterOperator
242 pParameters->FilterOperator =
243 (KMS_Agent::KMS_Agent__FilterOperator)
244 i_pSourceQueryParameters->m_aFilterParameters[i].m_eFilterOperator;
245 }
246
247 // copy PreviousPageLastIDValue
248 i_pQueryParameters->PreviousPageLastIDValue =
249 (utf8cstr) soap_malloc(i_pstSoap,
250 sizeof (i_pSourceQueryParameters->m_wsPreviousPageLastIDValue));
251 if (i_pQueryParameters->PreviousPageLastIDValue == NULL)
252 {
253 return (false);
254 }
255 strncpy(i_pQueryParameters->PreviousPageLastIDValue,
256 i_pSourceQueryParameters->m_wsPreviousPageLastIDValue,
257 sizeof (i_pSourceQueryParameters->m_wsPreviousPageLastIDValue));
258 i_pQueryParameters->PreviousPageLastIDValue[sizeof (i_pSourceQueryParameters->m_wsPreviousPageLastIDValue)-1] = '\0';
259
260 // copy PreviousPageLastIDValue
261 i_pQueryParameters->PreviousPageLastSortFieldValue =
262 (utf8cstr) soap_malloc(i_pstSoap,
263 sizeof (i_pSourceQueryParameters->
264 m_wsPreviousPageLastSortFieldValue));
265 if (i_pQueryParameters->PreviousPageLastSortFieldValue == NULL)
266 {
267 return (false);
268 }
269 strncpy(i_pQueryParameters->PreviousPageLastSortFieldValue,
270 i_pSourceQueryParameters->m_wsPreviousPageLastSortFieldValue,
271 sizeof (i_pSourceQueryParameters->
272 m_wsPreviousPageLastSortFieldValue));
273 i_pQueryParameters->PreviousPageLastSortFieldValue[sizeof (i_pSourceQueryParameters->
274 m_wsPreviousPageLastSortFieldValue)-1] = 0;
275
276 return (true);
277 }
278
CopyQueryParametersFromResponse(struct KMSAgent_QueryParameters * i_pQueryParameters,struct KMS_Agent::KMS_Agent__QueryParameters * i_pSourceQueryParameters)279 static void CopyQueryParametersFromResponse (
280 struct KMSAgent_QueryParameters *i_pQueryParameters,
281 struct KMS_Agent::KMS_Agent__QueryParameters *i_pSourceQueryParameters)
282 {
283
284 // copy sort field name
285 if (i_pSourceQueryParameters->SortFieldName)
286 {
287 strncpy(i_pQueryParameters->m_wsSortFieldName,
288 i_pSourceQueryParameters->SortFieldName,
289 sizeof(i_pQueryParameters->m_wsSortFieldName));
290 i_pQueryParameters->m_wsSortFieldName[sizeof(i_pQueryParameters->m_wsSortFieldName)-1] = '\0';
291 }
292
293 // copy order
294 i_pQueryParameters->m_eSortOrder =
295 (KMSAgent_SortOrder) i_pSourceQueryParameters->SortOrder;
296
297 // copy filter parameters
298 i_pQueryParameters->m_iSizeFilterParameters =
299 i_pSourceQueryParameters->FilterParameters.__size;
300
301 // we only accept this amount of parameters
302 if (i_pQueryParameters->m_iSizeFilterParameters >= KMS_MAX_AGENT_FILTER_PARAMETERS)
303 {
304 // this should not happen, but just for defending the code
305 i_pQueryParameters->m_iSizeFilterParameters = KMS_MAX_AGENT_FILTER_PARAMETERS;
306 }
307
308 for (int i = 0; i < i_pQueryParameters->m_iSizeFilterParameters; i++)
309 {
310 struct KMS_Agent::KMS_Agent__FilterParameters *pParameters;
311
312 pParameters = i_pSourceQueryParameters->FilterParameters.__ptr + i;
313
314 i_pQueryParameters->m_aFilterParameters[i].m_eFilterOperator
315 = (KMSAgent_FilterOperator) pParameters->FilterOperator;
316
317 if (pParameters->FieldName)
318 {
319 strncpy(i_pQueryParameters->m_aFilterParameters[i].m_wsFieldName,
320 pParameters->FieldName,
321 sizeof (i_pQueryParameters->m_aFilterParameters[i].m_wsFieldName));
322 i_pQueryParameters->
323 m_aFilterParameters[i].m_wsFieldName[sizeof (i_pQueryParameters->m_aFilterParameters[i].m_wsFieldName) - 1] = '\0';
324 }
325
326 if (pParameters->FieldValue)
327 {
328 strncpy(i_pQueryParameters->m_aFilterParameters[i].m_wsFieldValue,
329 pParameters->FieldValue,
330 sizeof(i_pQueryParameters->m_aFilterParameters[i].m_wsFieldValue));
331 i_pQueryParameters->
332 m_aFilterParameters[i].m_wsFieldValue[sizeof(i_pQueryParameters->m_aFilterParameters[i].m_wsFieldValue)-1] = '\0';
333 }
334 }
335 // copy PreviousPageLastIDValue
336 if (i_pSourceQueryParameters->PreviousPageLastIDValue)
337 {
338 strncpy(i_pQueryParameters->m_wsPreviousPageLastIDValue,
339 i_pSourceQueryParameters->PreviousPageLastIDValue,
340 sizeof(i_pQueryParameters->m_wsPreviousPageLastIDValue));
341 i_pQueryParameters->m_wsPreviousPageLastIDValue[sizeof(i_pQueryParameters->m_wsPreviousPageLastIDValue)-1] = '\0';
342 }
343
344 // copy PreviousPageLastSortFieldValue
345 if (i_pSourceQueryParameters->PreviousPageLastSortFieldValue)
346 {
347 strncpy(i_pQueryParameters->m_wsPreviousPageLastSortFieldValue,
348 i_pSourceQueryParameters->PreviousPageLastSortFieldValue,
349 sizeof(i_pQueryParameters->m_wsPreviousPageLastSortFieldValue));
350 i_pQueryParameters->m_wsPreviousPageLastSortFieldValue[sizeof(i_pQueryParameters->m_wsPreviousPageLastSortFieldValue)-1] = '\0';
351 }
352
353 }
354
355 /**
356 * copies data unit to the soap data unit structure, placing the xsd_string types on the
357 * gsoap heap.
358 * @return(false if soap_malloc fails
359 */
CopyDataUnitFromRequest(struct soap * i_pstSoap,struct KMS_Agent::KMS_Agent__DataUnit * i_pDataUnit,const KMSAgent_DataUnit * const i_pSourceDataUnit)360 static bool CopyDataUnitFromRequest (struct soap *i_pstSoap,
361 struct KMS_Agent::KMS_Agent__DataUnit *i_pDataUnit,
362 const KMSAgent_DataUnit * const i_pSourceDataUnit)
363 {
364
365 if (i_pSourceDataUnit)
366 {
367 // copy field name
368 i_pDataUnit->DataUnitID =
369 (utf8cstr) soap_malloc(i_pstSoap,
370 2 * sizeof (i_pSourceDataUnit->m_acDataUnitID) + 1);
371 if (i_pDataUnit->DataUnitID == NULL)
372 {
373 return (false);
374 }
375
376 ConvertBinaryToUTF8HexString(i_pDataUnit->DataUnitID,
377 i_pSourceDataUnit->m_acDataUnitID,
378 KMS_DATA_UNIT_ID_SIZE);
379 }
380 else
381 {
382 strcpy(i_pDataUnit->DataUnitID, "");
383 }
384
385 i_pDataUnit->ExternalUniqueID = (utf8cstr) soap_malloc(i_pstSoap,
386 2 * sizeof (i_pSourceDataUnit->m_acExternalUniqueID) + 1);
387 if (i_pDataUnit->ExternalUniqueID == NULL)
388 {
389 return (false);
390 }
391
392 if (i_pSourceDataUnit->m_iExternalUniqueIDLength > 0 &&
393 i_pSourceDataUnit->m_iExternalUniqueIDLength <= KMS_MAX_EXTERNAL_UNIQUE_ID_SIZE)
394 {
395 ConvertBinaryToUTF8HexString(i_pDataUnit->ExternalUniqueID,
396 i_pSourceDataUnit->m_acExternalUniqueID,
397 i_pSourceDataUnit->m_iExternalUniqueIDLength);
398 }
399 else
400 {
401 strcpy(i_pDataUnit->ExternalUniqueID, "");
402 }
403
404 i_pDataUnit->ExternalTag = (utf8cstr) soap_malloc(i_pstSoap, sizeof (i_pSourceDataUnit->m_acExternalTag));
405 if (i_pDataUnit->ExternalTag == NULL)
406 {
407 return (false);
408 }
409
410 if (strlen(i_pSourceDataUnit->m_acExternalTag) <= sizeof (i_pSourceDataUnit->m_acExternalTag))
411 {
412 strncpy(i_pDataUnit->ExternalTag,
413 i_pSourceDataUnit->m_acExternalTag,
414 sizeof (i_pSourceDataUnit->m_acExternalTag));
415 i_pDataUnit->ExternalTag[sizeof (i_pSourceDataUnit->m_acExternalTag)-1] = '\0';
416 }
417 else
418 {
419 strcpy(i_pDataUnit->ExternalTag, "");
420 }
421
422 i_pDataUnit->Description = (utf8cstr) soap_malloc(i_pstSoap, sizeof (i_pSourceDataUnit->m_acDescription));
423 if (i_pDataUnit->Description == NULL)
424 {
425 return (false);
426 }
427 if (strlen(i_pSourceDataUnit->m_acDescription) <= sizeof (i_pSourceDataUnit->m_acDescription))
428 {
429 strncpy(i_pDataUnit->Description,
430 i_pSourceDataUnit->m_acDescription,
431 sizeof (i_pSourceDataUnit->m_acDescription));
432 i_pDataUnit->Description[sizeof (i_pSourceDataUnit->m_acDescription)-1] = '\0';
433 }
434 else
435 {
436 strcpy(i_pDataUnit->Description, "");
437 }
438
439 i_pDataUnit->DataUnitState = (KMS_Agent::KMS_Agent__DataUnitState) i_pSourceDataUnit->m_iDataUnitState;
440
441 return (true);
442 }
443
444 /**
445 * Converts an ExternalUniqueID value to UTF8Hexstring value from gSoap managed heap storage
446 * @param i_pstSoap pointer to gSoap runtime
447 * @param i_pExternalUniqueID non-NULL pointer to an external unique id to be converted
448 * @return(NULL if memory cannot be allocated
449 */
ConvertBinaryDataFromRequest(struct soap * i_pstSoap,const unsigned char * i_pBinaryData,int i_iBinaryDataLen)450 static char * ConvertBinaryDataFromRequest (struct soap *i_pstSoap,
451 const unsigned char * i_pBinaryData,
452 int i_iBinaryDataLen)
453 {
454 char * pBinaryData = (char *) soap_malloc(i_pstSoap, 2 * i_iBinaryDataLen + 1);
455 if (pBinaryData != NULL)
456 {
457 ConvertBinaryToUTF8HexString(pBinaryData,
458 i_pBinaryData,
459 i_iBinaryDataLen);
460 }
461 return (pBinaryData);
462 }
463
464 /**
465 * Converts a UTF8 char string value to a fixed length array from
466 * gSoap managed heap storage
467 * @param pointer to gSoap runtime
468 * @param i_pUTF8string non-NULL pointer to a null terminated UTF8 string
469 * @param i_iLen size of arrray to be allocated
470 * @return(NULL if gSoap allocated storage could not be obtained
471 */
ConvertUTF8StringFromRequest(struct soap * i_pstSoap,const char * const i_pUTF8string,size_t i_iLen)472 static char * ConvertUTF8StringFromRequest (struct soap *i_pstSoap,
473 const char * const i_pUTF8string,
474 size_t i_iLen)
475 {
476 char * pUTF8string = NULL;
477 pUTF8string = (char *) soap_malloc(i_pstSoap, i_iLen);
478 if (pUTF8string != NULL)
479 {
480 strncpy(pUTF8string, i_pUTF8string, i_iLen);
481 pUTF8string[i_iLen-1] = '\0';
482 }
483 return (pUTF8string);
484 }
485
CopyKeyGroupsResponse(struct KMS_Agent::KMS_Agent__ArrayOfKeyGroups * i_pKeyGroupsResponse)486 static KMSAgent_ArrayOfKeyGroups * CopyKeyGroupsResponse
487 (
488 struct KMS_Agent::KMS_Agent__ArrayOfKeyGroups *i_pKeyGroupsResponse
489 )
490 {
491 // alloc memory for result
492 KMSAgent_ArrayOfKeyGroups *pResult =
493 (KMSAgent_ArrayOfKeyGroups *) calloc(1, sizeof (KMSAgent_ArrayOfKeyGroups));
494
495 // no memory, return
496 if (pResult == NULL)
497 {
498 return (NULL);
499 }
500
501 // copy size
502 pResult->m_iSize = i_pKeyGroupsResponse->__size;
503
504 // if the size is 0, return(an empty result
505 if (pResult->m_iSize == 0)
506 {
507 return (pResult);
508 }
509
510 // alloc memory for all key groups
511 pResult->m_pKeyGroups = (KMSAgent_KeyGroup*)
512 calloc(1, sizeof (KMSAgent_KeyGroup) * pResult->m_iSize);
513
514 if (pResult->m_pKeyGroups == NULL)
515 {
516 free(pResult);
517 return (NULL);
518 }
519
520 for (int i = 0; i < pResult->m_iSize; i++)
521 {
522 KMSAgent_KeyGroup *pKeyGroup;
523
524 pKeyGroup = &(pResult->m_pKeyGroups[i]);
525
526 strncpy(pKeyGroup->m_acKeyGroupID,
527 i_pKeyGroupsResponse->__ptr[i].KeyGroupID,
528 sizeof(pKeyGroup->m_acKeyGroupID));
529 pKeyGroup->m_acKeyGroupID[sizeof(pKeyGroup->m_acKeyGroupID)-1] = '\0';
530
531 strncpy(pKeyGroup->m_acDescription,
532 i_pKeyGroupsResponse->__ptr[i].Description,
533 sizeof(pKeyGroup->m_acDescription));
534 pKeyGroup->m_acDescription[sizeof(pKeyGroup->m_acDescription)-1] = '\0';
535 }
536
537 return (pResult);
538 }
539 /**
540 * allocate storage for the KMSAgent_ArrayOfKeys struct and the array of keys returned in the
541 * soap response.
542 * @param i_pProfile pointer to profile
543 * @param io_pClusterIndex pointer to the cluster index value which is used
544 * by AES Key Unwrap to access the KWK for the KMA corresponding to the
545 * cluster index.
546 * @param i_pKeysResponse pointer to the soap response' array of keys struct
547 * @return(pointer to allocated KMSAgent_ArrayOfKeys and the corresponding keys, returns NULL
548 * on any error and frees any allocated storage before returning. For response data validation errors a
549 * message will be logged.
550 */
CopyDataUnitKeysResponse(KMSClientProfile * i_pProfile,int * const io_pClusterIndex,struct KMS_Agent::KMS_Agent__ArrayOfKeys * i_pKeysResponse)551 static KMSAgent_ArrayOfKeys * CopyDataUnitKeysResponse (
552 KMSClientProfile *i_pProfile,
553 int * const io_pClusterIndex,
554 struct KMS_Agent::KMS_Agent__ArrayOfKeys *i_pKeysResponse)
555 {
556 KMSAgent_ArrayOfKeys * pResult =
557 (KMSAgent_ArrayOfKeys *) calloc(1, sizeof (KMSAgent_ArrayOfKeys));
558
559 if (pResult == NULL)
560 {
561 return (NULL);
562 }
563
564 // if the size is 0, return(an empty result
565 if (i_pKeysResponse->__size == 0)
566 {
567 return (pResult);
568 }
569
570 if (i_pKeysResponse->__size > KMS_MAX_PAGE_SIZE)
571 {
572 free(pResult);
573 LogError(i_pProfile,
574 AUDIT_CLIENT_AGENT_RETRIEVE_DATA_UNIT_KEYS_INVALID_KEY_ARRAY_SIZE_RESPONSE,
575 NULL,
576 NULL,
577 NULL);
578 return (NULL);
579 }
580
581 pResult->m_iSize = i_pKeysResponse->__size;
582
583 // alloc memory for all keys returned
584 pResult->m_pKeys = (KMSAgent_Key*)
585 calloc(1, sizeof (KMSAgent_Key) * i_pKeysResponse->__size);
586
587 if (pResult->m_pKeys == NULL)
588 {
589 free(pResult);
590 return (NULL);
591 // no memory, don't log
592 }
593
594 // copy keys from response
595 for (int i = 0; i < i_pKeysResponse->__size; i++)
596 {
597 if (KMS_KEY_ID_SIZE != ConvertUTF8HexStringToBinary(
598 i_pKeysResponse->__ptr[i].KeyID, NULL))
599 {
600 free(pResult->m_pKeys);
601 free(pResult);
602
603 LogError(i_pProfile,
604 AUDIT_CLIENT_AGENT_RETRIEVE_DATA_UNIT_KEYS_INVALID_KEY_RESPONSE,
605 NULL,
606 NULL,
607 NULL);
608 return (NULL);
609 }
610
611 ConvertUTF8HexStringToBinary(
612 i_pKeysResponse->__ptr[i].KeyID, pResult->m_pKeys[i].m_acKeyID);
613
614 if ((KMS_AGENT_KEY_STATE) i_pKeysResponse->__ptr[i].KeyState < KMS_KEY_STATE_ACTIVE_PROTECT_AND_PROCESS ||
615 (KMS_AGENT_KEY_STATE) i_pKeysResponse->__ptr[i].KeyState > KMS_KEY_STATE_COMPROMISED)
616 {
617 free(pResult->m_pKeys);
618 free(pResult);
619 LogError(i_pProfile,
620 AUDIT_CLIENT_AGENT_RETRIEVE_DATA_UNIT_KEYS_INVALID_KEY_STATE_RESPONSE,
621 NULL,
622 NULL,
623 NULL);
624 return (NULL);
625 }
626 pResult->m_pKeys[i].m_iKeyState = (KMS_AGENT_KEY_STATE) i_pKeysResponse->__ptr[i].KeyState;
627
628 if ((KMS_KEY_TYPE) i_pKeysResponse->__ptr[i].KeyType != (KMS_KEY_TYPE)KMS_KEY_TYPE_AES_256)
629 {
630 free(pResult->m_pKeys);
631 free(pResult);
632 LogError(i_pProfile,
633 AUDIT_CLIENT_AGENT_RETRIEVE_DATA_UNIT_KEYS_INVALID_KEY_TYPE_RESPONSE,
634 NULL,
635 NULL,
636 NULL);
637 return (NULL);
638 }
639 pResult->m_pKeys[i].m_iKeyType = (KMS_KEY_TYPE) i_pKeysResponse->__ptr[i].KeyType;
640
641 strncpy(pResult->m_pKeys[i].m_acKeyGroupID,
642 i_pKeysResponse->__ptr[i].KeyGroupID,
643 sizeof(pResult->m_pKeys[i].m_acKeyGroupID));
644 pResult->m_pKeys[i].m_acKeyGroupID[sizeof(pResult->m_pKeys[i].m_acKeyGroupID)-1] = '\0';
645
646 CAgentLoadBalancer *pAgentLoadBalancer = reinterpret_cast
647 <CAgentLoadBalancer *> (i_pProfile->m_pAgentLoadBalancer);
648
649 if (pAgentLoadBalancer->AESKeyWrapSupported(*io_pClusterIndex))
650 {
651 if (i_pKeysResponse->__ptr[i].Key.__size != KMS_MAX_WRAPPED_KEY_SIZE)
652 {
653 free(pResult->m_pKeys);
654 free(pResult);
655 LogError(i_pProfile,
656 AUDIT_CLIENT_AGENT_RETRIEVE_DATA_UNIT_KEYS_INVALID_WRAPPED_KEY_LENGTH_RESPONSE,
657 NULL,
658 NULL,
659 NULL);
660 return (NULL);
661 }
662 else
663 {
664 if (pAgentLoadBalancer->AESKeyUnwrap(io_pClusterIndex,
665 i_pKeysResponse->__ptr[i].Key.__ptr,
666 pResult->m_pKeys[i].m_acKey) == false)
667 {
668 free(pResult->m_pKeys);
669 free(pResult);
670 LogError(i_pProfile,
671 AUDIT_CLIENT_AGENT_RETRIEVE_DATA_UNIT_KEYS_AESKEYUNWRAP_ERROR,
672 NULL,
673 NULL,
674 NULL);
675
676 return (NULL);
677 }
678 }
679 }
680 else // non-AES Key Wrap
681 {
682 if (i_pKeysResponse->__ptr[i].Key.__size != KMS_MAX_KEY_SIZE)
683 {
684 free(pResult->m_pKeys);
685 free(pResult);
686 LogError(i_pProfile,
687 AUDIT_CLIENT_AGENT_RETRIEVE_DATA_UNIT_KEYS_INVALID_KEY_LENGTH_RESPONSE,
688 NULL,
689 NULL,
690 NULL);
691 return (NULL);
692 }
693
694 memcpy(pResult->m_pKeys[i].m_acKey,
695 i_pKeysResponse->__ptr[i].Key.__ptr,
696 KMS_MAX_KEY_SIZE);
697 }
698
699 pResult->m_pKeys[i].m_iKeyLength = KMS_MAX_KEY_SIZE;
700
701 if (KMSAgentKeyCallout(pResult->m_pKeys[i].m_acKey) != 0)
702 {
703 free(pResult->m_pKeys);
704 free(pResult);
705 LogError(i_pProfile,
706 AUDIT_CLIENT_AGENT_RETRIEVE_DATA_UNIT_KEYS_KEY_CALLOUT_ERROR,
707 NULL,
708 NULL,
709 NULL);
710 return (NULL);
711 }
712 }
713
714 return (pResult);
715 }
716
717 /**
718 * This function returns the API status code based upon the error string in the profile and
719 * availability of KMAs. KMA availability determination is based upon the i_iKMAFailoverReturnCode
720 * parameter and the size of the cluster. A cluster size of 0 is an indicator that there are
721 * no KMAs available, unless cluster discovery is disabled by the profile's cluster discovery
722 * frequency.
723 *
724 * @param i_pProfile pointer to the profile
725 * @param i_iKMAFailoverReturnCode the return(code from CAgentLoadBalancer::Failover() or 0
726 * if it was not called. This is used to for determining if KMS_AGENT_STATUS_KMS_UNAVAILABLE
727 * needs to be returned.
728 * @returns KMS_AGENT_STATUS_GENERIC_ERROR
729 * unless the profile's last error message field contains a message substring matching one of the
730 * KMSAgent service soap fault strings.
731 *
732 */
KMSAgent_GetLastStatusCode(KMSClientProfile * i_pProfile,int i_iKMAFailoverReturnCode)733 static KMS_AGENT_STATUS KMSAgent_GetLastStatusCode (KMSClientProfile *i_pProfile,
734 int i_iKMAFailoverReturnCode)
735 {
736 bool bServerError = false;
737
738 FATAL_ASSERT(i_pProfile);
739
740 // see KMSAgentLoadBalancer.h for return codes from Failover
741
742 if (i_iKMAFailoverReturnCode == CAgentLoadBalancer::NO_FIPS_KMA_AVAILABLE)
743 {
744 return (KMS_AGENT_STATUS_NO_FIPS_KMAS_AVAILABLE);
745 }
746
747 // parse for server errors -
748 // when KMAs have no ready keys we want to inform the client, vs reporting that the KMS is unavailable
749 bServerError = ServerError(i_pProfile->m_wsErrorString, 0);
750
751 // parse for Soap errors
752 const char* sFaultstringStart = strstr(i_pProfile->m_wsErrorString, "SoapFaultString=");
753
754 int iErrorCode = INVALID_CLIENT_ERROR; // initially
755
756
757 // if there is a Soap error
758 if (sFaultstringStart)
759 {
760 if (SSL_InvalidCertificate(sFaultstringStart))
761 {
762 // this can be caused by the KMS invalidating the agent's cert
763 return (KMS_AGENT_STATUS_ACCESS_DENIED);
764 }
765 iErrorCode = GET_FAULT_CODE(sFaultstringStart + strlen("SoapFaultString="));
766 }
767
768
769 #ifdef METAWARE
770 // log the failure code/cause to the event log
771 LogToFile(i_iKMAFailoverReturnCode, i_pProfile->m_wsErrorString);
772 LogToFile(iErrorCode, "error code");
773 #endif
774
775
776 // parse return code passed in from last call to FailOver, Balance or BalanceByDataUnitKeyID
777 // if failover reported no kma and there is a valid server error and client couldn't get keys
778 if (i_iKMAFailoverReturnCode == CAgentLoadBalancer::NO_KMA_AVAILABLE &&
779 bServerError &&
780 iErrorCode == CLIENT_ERROR_AGENT_NO_READY_KEYS)
781 {
782 return (KMS_AGENT_STATUS_KMS_UNAVAILABLE);
783 }
784
785 // if there is a server error and we are doing discovery
786 if (bServerError &&
787 ((i_pProfile->m_iClusterDiscoveryFrequency > 0 &&
788 i_pProfile->m_iClusterNum == 0)
789 || iErrorCode == CLIENT_ERROR_AGENT_APPLIANCE_LOCKED))
790 {
791 return (KMS_AGENT_STATUS_KMS_UNAVAILABLE);
792 }
793
794 if (bServerError && i_iKMAFailoverReturnCode == CAgentLoadBalancer::NO_KMA_AVAILABLE)
795 {
796 return (KMS_AGENT_STATUS_KMS_UNAVAILABLE);
797 }
798
799 if ( i_iKMAFailoverReturnCode == CAgentLoadBalancer::AES_KEY_UNWRAP_ERROR )
800 return (KMS_AGENT_AES_KEY_UNWRAP_ERROR);
801 if ( i_iKMAFailoverReturnCode == CAgentLoadBalancer::AES_KEY_WRAP_SETUP_ERROR )
802 return (KMS_AGENT_AES_KEY_WRAP_SETUP_ERROR);
803
804 if (iErrorCode == CLIENT_ERROR_ACCESS_DENIED)
805 return (KMS_AGENT_STATUS_ACCESS_DENIED);
806 if (iErrorCode == CLIENT_ERROR_SERVER_BUSY)
807 return (KMS_AGENT_STATUS_SERVER_BUSY);
808 if (iErrorCode == CLIENT_ERROR_AGENT_INVALID_PARAMETERS)
809 return (KMS_AGENT_STATUS_INVALID_PARAMETER);
810 if (iErrorCode == CLIENT_ERROR_AGENT_KEY_DOES_NOT_EXIST)
811 return (KMS_AGENT_STATUS_KEY_DOES_NOT_EXIST);
812 if (iErrorCode == CLIENT_ERROR_AGENT_KEY_DESTROYED)
813 return (KMS_AGENT_STATUS_KEY_DESTROYED);
814 if (iErrorCode == CLIENT_ERROR_AGENT_DATA_UNIT_ID_NOT_FOUND_EXTERNAL_ID_EXISTS)
815 return (KMS_AGENT_STATUS_DATA_UNIT_ID_NOT_FOUND_EXTERNAL_ID_EXISTS);
816 if (iErrorCode == CLIENT_ERROR_AGENT_DUPLICATE_EXTERNAL_ID)
817 return (KMS_AGENT_STATUS_EXTERNAL_UNIQUE_ID_EXISTS);
818 if (iErrorCode == CLIENT_ERROR_AGENT_NO_READY_KEYS)
819 return (KMS_AGENT_STATUS_KMS_NO_READY_KEYS);
820
821 // this check is made last to allow other specific errors that may have occurred to take precedence,
822 // e.g. return access denied before reporting No FIPS KMAs
823 if (i_pProfile->m_eKMSmode == FIPS_MODE &&
824 KMSClient_NoFIPSCompatibleKMAs(i_pProfile))
825 {
826 return (KMS_AGENT_STATUS_NO_FIPS_KMAS_AVAILABLE);
827 }
828
829 return (KMS_AGENT_STATUS_GENERIC_ERROR);
830 }
831
832 /*---------------------------------------------------------------------------
833 * Function: KMSAgent_InitializeLibrary
834 *--------------------------------------------------------------------------*/
835 #include "KMSAuditLogger.h"
836
837 extern "C"
KMSAgent_InitializeLibrary(utf8cstr const i_pWorkingDirectory,int i_bUseFileLog)838 KMS_AGENT_STATUS KMSAgent_InitializeLibrary (utf8cstr const i_pWorkingDirectory,
839 int i_bUseFileLog)
840
841 {
842 bool bSuccess;
843
844 #if defined(METAWARE)
845 #warn "debug timing is on"
846 ECPT_TRACE_ENTRY *trace = NULL;
847 ECPT_TRACE(trace, KMSAgent_InitializeLibrary);
848 #endif
849
850 #if defined(DEBUG) && defined(METAWARE)
851 log_printf("KMSAgent_InitializeLibrary : Entered");
852 #endif
853
854 bSuccess = KMSClient_InitializeLibrary(
855 i_pWorkingDirectory,
856 i_bUseFileLog);
857
858 if (bSuccess)
859 {
860 RETURN(KMS_AGENT_STATUS_OK);
861 }
862
863 RETURN(KMS_AGENT_STATUS_GENERIC_ERROR);
864 }
865
866 /*---------------------------------------------------------------------------
867 * Function: KMSAgent_KnownAnswerTests
868 *
869 *--------------------------------------------------------------------------*/
KMSAgent_KnownAnswerTests()870 KMS_AGENT_STATUS KMSAgent_KnownAnswerTests()
871 {
872 #if defined(METAWARE)
873 ECPT_TRACE_ENTRY *trace = NULL;
874 ECPT_TRACE(trace, KMSAgent_KnownAnswerTests);
875 #endif
876
877 // Known Answer Test on AES Key Wrap code
878 if ( KnownAnswerTestAESKeyWrap() != 0 )
879 {
880 RETURN(KMS_AGENT_STATUS_FIPS_KAT_AES_KEYWRAP_ERROR);
881 }
882
883 if ( KnownAnswerTestAESECB() != 0 )
884 {
885 RETURN(KMS_AGENT_STATUS_FIPS_KAT_AES_ECB_ERROR);
886 }
887
888 if ( KnownAnswerTestHMACSHA1() != 0 )
889 {
890 RETURN(KMS_AGENT_STATUS_FIPS_KAT_HMAC_SHA1_ERROR);
891 }
892
893 RETURN(KMS_AGENT_STATUS_OK);
894
895 }
896
897 /*---------------------------------------------------------------------------
898 * Function: KMSAgent_FinalizeLibrary
899 *
900 *--------------------------------------------------------------------------*/
901
902 extern "C"
KMSAgent_FinalizeLibrary()903 KMS_AGENT_STATUS KMSAgent_FinalizeLibrary ()
904 {
905 bool bSuccess;
906
907 #if defined(METAWARE)
908 ECPT_TRACE_ENTRY *trace = NULL;
909 ECPT_TRACE(trace, KMSAgent_FinalizeLibrary);
910 #endif
911
912 bSuccess = KMSClient_FinalizeLibrary();
913
914 if (bSuccess)
915 {
916 RETURN(KMS_AGENT_STATUS_OK);
917 }
918
919 RETURN(KMS_AGENT_STATUS_GENERIC_ERROR);
920 }
921
922 /*---------------------------------------------------------------------------
923 * Function: KMSAgent_GetLastErrorMessage
924 *
925 *--------------------------------------------------------------------------*/
926
927 extern "C"
KMSAgent_GetLastErrorMessage(KMSClientProfile * i_pProfile)928 utf8cstr KMSAgent_GetLastErrorMessage (KMSClientProfile* i_pProfile)
929 {
930 #if defined(METAWARE)
931 ECPT_TRACE_ENTRY *trace = NULL;
932 ECPT_TRACE(trace, KMSAgent_GetLastErrorMessage);
933 #endif
934
935 if (i_pProfile == NULL)
936 {
937 RETURN(NULL);
938 }
939
940 RETURN(KMSClient_GetLastErrorMessage(i_pProfile));
941 }
942
943 /*---------------------------------------------------------------------------
944 * Function: KMSAgent_GetClusterInformation
945 *
946 *--------------------------------------------------------------------------*/
947 extern "C"
KMSAgent_GetClusterInformation(KMSClientProfile * const i_pProfile,int i_iEntitySiteIDSize,int i_iClusterEntryArraySize,utf8cstr const o_pEntitySiteID,int * const o_pApplianceNum,KMSClusterEntry * const o_pClusterEntryArray)948 KMS_AGENT_STATUS KMSAgent_GetClusterInformation (
949 KMSClientProfile * const i_pProfile,
950 int i_iEntitySiteIDSize,
951 int i_iClusterEntryArraySize,
952 utf8cstr const o_pEntitySiteID,
953 int * const o_pApplianceNum,
954 KMSClusterEntry * const o_pClusterEntryArray)
955 {
956 bool bSuccess;
957 #if defined(METAWARE)
958 ECPT_TRACE_ENTRY *trace = NULL;
959 ECPT_TRACE(trace, KMSAgent_GetClusterInformation);
960 #endif
961
962 if (!i_pProfile)
963 {
964 Log(AUDIT_CLIENT_AGENT_GET_CLUSTER_INFORMATION_INVALID_PARAMETERS,
965 NULL,
966 NULL,
967 "Profile arg");
968 RETURN(KMS_AGENT_STATUS_INVALID_PARAMETER);
969 }
970
971 if (!o_pEntitySiteID || (i_iEntitySiteIDSize <= (KMS_MAX_ENTITY_SITE_ID)))
972 {
973 Log(AUDIT_CLIENT_AGENT_GET_CLUSTER_INFORMATION_INVALID_PARAMETERS,
974 NULL,
975 NULL,
976 "EntitySiteIDSize arg");
977 RETURN(KMS_AGENT_STATUS_INVALID_PARAMETER);
978 }
979
980 if (i_iClusterEntryArraySize > KMS_MAX_CLUSTER_NUM)
981 {
982 Log(AUDIT_CLIENT_AGENT_GET_CLUSTER_INFORMATION_INVALID_PARAMETERS,
983 NULL,
984 NULL,
985 "i_iClusterEntryArraySize exceeds KMS_MAX_CLUSTER_NUM");
986 RETURN(KMS_AGENT_STATUS_INVALID_PARAMETER);
987 }
988
989 if (!o_pApplianceNum)
990 {
991 Log(AUDIT_CLIENT_AGENT_GET_CLUSTER_INFORMATION_INVALID_PARAMETERS,
992 NULL,
993 NULL,
994 "ApplianceNum arg");
995 RETURN(KMS_AGENT_STATUS_INVALID_PARAMETER);
996 }
997
998 if (!o_pClusterEntryArray ||
999 (i_iClusterEntryArraySize <= 0))
1000 {
1001 Log(AUDIT_CLIENT_AGENT_GET_CLUSTER_INFORMATION_INVALID_PARAMETERS,
1002 NULL,
1003 NULL,
1004 "ClusterEntry or Size arg");
1005 RETURN(KMS_AGENT_STATUS_INVALID_PARAMETER);
1006 }
1007
1008 if (!KMSClient_ProfileLoaded(i_pProfile))
1009 {
1010 RETURN(KMS_AGENT_STATUS_PROFILE_NOT_LOADED);
1011 }
1012
1013 CAutoMutex oAutoMutex((K_MUTEX_HANDLE) i_pProfile->m_pLock);
1014
1015 bSuccess = KMSClient_GetClusterInformation(
1016 i_pProfile,
1017 o_pEntitySiteID,
1018 i_iEntitySiteIDSize,
1019 o_pApplianceNum,
1020 o_pClusterEntryArray,
1021 i_iClusterEntryArraySize);
1022
1023 // KMSClient_GetClusterInformation logs if there was an error
1024
1025 if (bSuccess)
1026 {
1027 RETURN(KMS_AGENT_STATUS_OK);
1028 }
1029
1030 RETURN(KMSAgent_GetLastStatusCode(i_pProfile, 0));
1031 }
1032
1033 extern "C"
KMSAgent_SelectAppliance(KMSClientProfile * const i_pProfile,utf8cstr const i_pApplianceAddress)1034 KMS_AGENT_STATUS KMSAgent_SelectAppliance (
1035 KMSClientProfile * const i_pProfile,
1036 utf8cstr const i_pApplianceAddress)
1037 {
1038 bool bSuccess;
1039 #if defined(METAWARE)
1040 ECPT_TRACE_ENTRY *trace = NULL;
1041 ECPT_TRACE(trace, KMSAgent_SelectAppliance);
1042 #endif
1043
1044 if (!i_pProfile)
1045 {
1046 Log(AUDIT_CLIENT_AGENT_SELECT_APPLIANCE_INVALID_PARAMETERS,
1047 NULL,
1048 NULL,
1049 "Profile arg");
1050 RETURN(KMS_AGENT_STATUS_INVALID_PARAMETER);
1051 }
1052 if (!i_pApplianceAddress)
1053 {
1054 Log(AUDIT_CLIENT_AGENT_GET_CLUSTER_INFORMATION_INVALID_PARAMETERS,
1055 NULL,
1056 NULL,
1057 "ApplianceAddress arg");
1058 RETURN(KMS_AGENT_STATUS_INVALID_PARAMETER);
1059 }
1060
1061 if (!KMSClient_ProfileLoaded(i_pProfile))
1062 {
1063 RETURN(KMS_AGENT_STATUS_PROFILE_NOT_LOADED);
1064 }
1065
1066 // All modes are supported by this function.
1067
1068 bSuccess = KMSClient_SelectAppliance(i_pProfile, i_pApplianceAddress);
1069
1070 if (bSuccess)
1071 {
1072 RETURN(KMS_AGENT_STATUS_OK);
1073 }
1074
1075 RETURN(KMSAgent_GetLastStatusCode(i_pProfile, 0));
1076 }
1077
1078 /*---------------------------------------------------------------------------
1079 * Function: KMSAgent_LoadProfile
1080 *
1081 *--------------------------------------------------------------------------*/
1082 extern "C"
KMSAgent_LoadProfile(KMSClientProfile * const io_pProfile,utf8cstr const i_pProfileName,utf8cstr const i_pAgentID,utf8cstr const i_pPassphrase,utf8cstr const i_pInitialApplianceAddress,int i_iTransactionTimeout,int i_iFailOverLimit,int i_iClusterDiscoveryFrequency,int i_eKMSmode)1083 KMS_AGENT_STATUS KMSAgent_LoadProfile (
1084 KMSClientProfile * const io_pProfile,
1085 utf8cstr const i_pProfileName,
1086 utf8cstr const i_pAgentID,
1087 utf8cstr const i_pPassphrase,
1088 utf8cstr const i_pInitialApplianceAddress,
1089 int i_iTransactionTimeout,
1090 int i_iFailOverLimit,
1091 int i_iClusterDiscoveryFrequency,
1092 int i_eKMSmode)
1093 {
1094 bool bSuccess;
1095 #if defined(METAWARE)
1096 ECPT_TRACE_ENTRY *trace = NULL;
1097 ECPT_TRACE(trace, KMSAgent_LoadProfile);
1098 #endif
1099
1100 #if defined(DEBUG) && defined(METAWARE)
1101 log_printf("KMSAgent_LoadProfile : Entered");
1102 #endif
1103 if (!io_pProfile ||
1104 !i_pProfileName || (strlen(i_pProfileName) <= 0))
1105 {
1106 Log(AUDIT_CLIENT_AGENT_LOAD_PROFILE_INVALID_PARAMETERS,
1107 NULL,
1108 NULL,
1109 "Profile or Name arg");
1110 RETURN(KMS_AGENT_STATUS_INVALID_PARAMETER);
1111 }
1112 if (!i_pInitialApplianceAddress || (strlen(i_pInitialApplianceAddress) <= 0))
1113 {
1114 Log(AUDIT_CLIENT_AGENT_LOAD_PROFILE_INVALID_PARAMETERS,
1115 NULL,
1116 NULL,
1117 "InitialApplianceAddress arg");
1118 RETURN(KMS_AGENT_STATUS_INVALID_PARAMETER);
1119 }
1120
1121 if (i_iTransactionTimeout <= 0)
1122 {
1123 Log(AUDIT_CLIENT_AGENT_LOAD_PROFILE_INVALID_PARAMETERS,
1124 NULL,
1125 NULL,
1126 "TransactionTimeout arg");
1127 RETURN(KMS_AGENT_STATUS_INVALID_PARAMETER);
1128 }
1129 if (i_iClusterDiscoveryFrequency < 0)
1130 {
1131 Log(AUDIT_CLIENT_AGENT_LOAD_PROFILE_INVALID_PARAMETERS,
1132 NULL,
1133 NULL,
1134 "ClusterDiscoveryFrequency arg");
1135 RETURN(KMS_AGENT_STATUS_INVALID_PARAMETER);
1136 }
1137
1138 // for enrollment both arguments are required
1139 if ((i_pAgentID && !i_pPassphrase) || (i_pPassphrase && !i_pAgentID))
1140 {
1141 Log(AUDIT_CLIENT_AGENT_LOAD_PROFILE_INVALID_PARAMETERS,
1142 NULL,
1143 NULL,
1144 "Enrollment requires AgentID & Passphrase");
1145 RETURN(KMS_AGENT_STATUS_INVALID_PARAMETER);
1146 }
1147
1148 if (i_pAgentID && (strlen(i_pAgentID) <= 0))
1149 {
1150 Log(AUDIT_CLIENT_AGENT_LOAD_PROFILE_INVALID_PARAMETERS,
1151 NULL,
1152 NULL,
1153 "AgentID arg");
1154 RETURN(KMS_AGENT_STATUS_INVALID_PARAMETER);
1155 }
1156
1157 if (i_pPassphrase && (strlen(i_pPassphrase) <= 0))
1158 {
1159 Log(AUDIT_CLIENT_AGENT_LOAD_PROFILE_INVALID_PARAMETERS,
1160 NULL,
1161 NULL,
1162 "Passphrase arg");
1163 RETURN(KMS_AGENT_STATUS_INVALID_PARAMETER);
1164 }
1165
1166 if ( i_eKMSmode != DEFAULT_MODE && i_eKMSmode != FIPS_MODE )
1167 {
1168 Log(AUDIT_CLIENT_AGENT_LOAD_PROFILE_INVALID_PARAMETERS,
1169 NULL,
1170 NULL,
1171 "KMS security mode arg");
1172 RETURN(KMS_AGENT_STATUS_INVALID_PARAMETER);
1173 }
1174
1175 if (KMSClient_ProfileLoaded(io_pProfile))
1176 {
1177 Log(AUDIT_CLIENT_AGENT_LOAD_PROFILE_PROFILE_ALREADY_LOADED,
1178 NULL,
1179 NULL,
1180 "profile is already loaded and should be unloaded first");
1181 RETURN(KMS_AGENT_STATUS_PROFILE_ALREADY_LOADED);
1182 }
1183
1184 memset(io_pProfile, 0, sizeof (KMSClientProfile));
1185 char sInitialApplianceAddress[KMS_MAX_NETWORK_ADDRESS+1];
1186 strncpy(sInitialApplianceAddress, i_pInitialApplianceAddress, sizeof(sInitialApplianceAddress));
1187 sInitialApplianceAddress[sizeof(sInitialApplianceAddress)-1] = '\0';
1188
1189 // Convert to lower case
1190
1191 for ( size_t i = 0; i < strlen( sInitialApplianceAddress ); i++ )
1192 {
1193 if ( isupper( sInitialApplianceAddress[i] ) )
1194 {
1195 sInitialApplianceAddress[i] = tolower( sInitialApplianceAddress[i] );
1196 }
1197 }
1198
1199 bSuccess = KMSClient_LoadProfile(
1200 io_pProfile,
1201 i_pProfileName,
1202 i_pAgentID,
1203 i_pPassphrase,
1204 sInitialApplianceAddress,
1205 i_iTransactionTimeout,
1206 i_iFailOverLimit,
1207 i_iClusterDiscoveryFrequency,
1208 i_eKMSmode);
1209
1210 if (bSuccess)
1211 {
1212 #if defined(DEBUG) && defined(METAWARE)
1213 log_printf("KMSAgent_LoadProfile : Returned ok");
1214 #endif
1215 RETURN(KMS_AGENT_STATUS_OK);
1216 }
1217
1218 // when not enrolling & cluster discovery is disabled there are no
1219 // soap transactions so failover would not have occurred
1220 bool bEnrolling = i_pAgentID && i_pPassphrase;
1221
1222 if (!bEnrolling &&
1223 i_iClusterDiscoveryFrequency == 0)
1224 {
1225 RETURN(KMSAgent_GetLastStatusCode(io_pProfile, 0));
1226 }
1227 else
1228 {
1229 // if (i_eKMSmode == FIPS_MODE &&
1230 // KMSClient_NoFIPSCompatibleKMAs(io_pProfile))
1231 // {
1232 // RETURN(KMSAgent_GetLastStatusCode(io_pProfile,
1233 // CAgentLoadBalancer::NO_FIPS_KMA_AVAILABLE));
1234 // }
1235
1236 RETURN(KMSAgent_GetLastStatusCode(io_pProfile,
1237 CAgentLoadBalancer::NO_KMA_AVAILABLE));
1238 }
1239 }
1240
1241 /*---------------------------------------------------------------------------
1242 * Function: KMSAgent_UnloadProfile
1243 *
1244 *--------------------------------------------------------------------------*/
1245 extern "C"
KMSAgent_UnloadProfile(KMSClientProfile * const i_pProfile)1246 KMS_AGENT_STATUS KMSAgent_UnloadProfile (KMSClientProfile * const i_pProfile)
1247 {
1248 bool bSuccess;
1249 #if defined(METAWARE)
1250 ECPT_TRACE_ENTRY *trace = NULL;
1251 ECPT_TRACE(trace, KMSAgent_UnloadProfile);
1252 #endif
1253
1254 if (!i_pProfile)
1255 {
1256 Log(AUDIT_CLIENT_AGENT_UNLOAD_PROFILE_INVALID_PARAMETERS,
1257 NULL,
1258 NULL,
1259 "Profile arg");
1260 RETURN(KMS_AGENT_STATUS_INVALID_PARAMETER);
1261 }
1262
1263 if (!KMSClient_ProfileLoaded(i_pProfile))
1264 {
1265 RETURN(KMS_AGENT_STATUS_PROFILE_NOT_LOADED);
1266 }
1267
1268 bSuccess = KMSClient_UnloadProfile(i_pProfile);
1269
1270 if (bSuccess)
1271 {
1272 RETURN(KMS_AGENT_STATUS_OK);
1273 }
1274
1275 RETURN(KMSAgent_GetLastStatusCode(i_pProfile, 0));
1276 }
1277
1278 /*---------------------------------------------------------------------------
1279 * Function: KMSAgent_DeleteProfile
1280 *
1281 *--------------------------------------------------------------------------*/
1282 extern "C"
KMSAgent_DeleteProfile(utf8cstr i_pProfileName)1283 KMS_AGENT_STATUS KMSAgent_DeleteProfile (utf8cstr i_pProfileName)
1284 {
1285 bool bSuccess;
1286 #if defined(METAWARE)
1287 ECPT_TRACE_ENTRY *trace = NULL;
1288 ECPT_TRACE(trace, KMSAgent_DeleteProfile);
1289 #endif
1290
1291 if (!i_pProfileName || (strlen(i_pProfileName) <= 0))
1292 {
1293 RETURN(KMS_AGENT_STATUS_INVALID_PARAMETER);
1294 }
1295
1296 bSuccess = KMSClient_DeleteProfile(i_pProfileName);
1297
1298 if (bSuccess)
1299 {
1300 RETURN(KMS_AGENT_STATUS_OK);
1301 }
1302
1303 RETURN(KMS_AGENT_STATUS_GENERIC_ERROR);
1304 }
1305
1306 /*---------------------------------------------------------------------------
1307 * Function: KMSAgent_ListKeyGroups
1308 *
1309 *--------------------------------------------------------------------------*/
1310
1311 extern "C"
KMSAgent_ListKeyGroups(KMSClientProfile * const i_pProfile,KMSAgent_ArrayOfKeyGroups ** const o_ppKeyGroups)1312 KMS_AGENT_STATUS KMSAgent_ListKeyGroups (
1313 KMSClientProfile * const i_pProfile,
1314 KMSAgent_ArrayOfKeyGroups* * const o_ppKeyGroups)
1315 {
1316 bool bSuccess;
1317 #if defined(METAWARE)
1318 ECPT_TRACE_ENTRY *trace = NULL;
1319 ECPT_TRACE(trace, KMSAgent_ListKeyGroups);
1320 #endif
1321
1322 int bIsLastPage;
1323 struct KMSAgent_QueryParameters stQueryParameters;
1324
1325 if (!i_pProfile)
1326 {
1327 Log(AUDIT_CLIENT_AGENT_LIST_KEY_GROUPS_INVALID_PARAMETERS,
1328 NULL,
1329 NULL,
1330 "Profile arg");
1331 RETURN(KMS_AGENT_STATUS_INVALID_PARAMETER);
1332 }
1333 if (!o_ppKeyGroups)
1334 {
1335 Log(AUDIT_CLIENT_AGENT_LIST_KEY_GROUPS_INVALID_PARAMETERS,
1336 NULL,
1337 NULL,
1338 "KeyGroups arg");
1339 RETURN(KMS_AGENT_STATUS_INVALID_PARAMETER);
1340 }
1341
1342 if (!KMSClient_ProfileLoaded(i_pProfile))
1343 {
1344 RETURN(KMS_AGENT_STATUS_PROFILE_NOT_LOADED);
1345 }
1346
1347 CAutoMutex oAutoMutex((K_MUTEX_HANDLE) i_pProfile->m_pLock);
1348
1349 struct soap *pstSoap = (struct soap *) i_pProfile->m_pvSoap;
1350
1351 // Get Key Groups
1352 memset(&stQueryParameters, 0, sizeof (stQueryParameters));
1353
1354 struct KMS_Agent::KMS_Agent__QueryParameters oQueryParameters;
1355 struct KMS_Agent::KMS_Agent__ListKeyGroupsResponse oResponse;
1356
1357 memset(&oQueryParameters, 0, sizeof (oQueryParameters));
1358
1359 bSuccess = CopyQueryParametersFromRequest(pstSoap,
1360 KMS_MAX_LIST_KEY_GROUPS,
1361 &oQueryParameters,
1362 &stQueryParameters);
1363 if (!bSuccess)
1364 {
1365 soap_destroy(pstSoap);
1366 soap_end(pstSoap);
1367 // no memory, don't log
1368 RETURN(KMS_AGENT_STATUS_NO_MEMORY);
1369 }
1370
1371 CAgentLoadBalancer *pLoadBalancer =
1372 (CAgentLoadBalancer *) i_pProfile->m_pAgentLoadBalancer;
1373
1374 int iIndex = pLoadBalancer->Balance();
1375
1376 if ( iIndex >= 0 )
1377 {
1378 do
1379 {
1380 const char* sURL =
1381 pLoadBalancer->GetHTTPSURL(iIndex, i_pProfile->m_iPortForAgentService);
1382 strncpy(i_pProfile->m_sURL, sURL, sizeof(i_pProfile->m_sURL));
1383 i_pProfile->m_sURL[sizeof(i_pProfile->m_sURL)-1] = '\0';
1384
1385 bSuccess = KMS_Agent::soap_call_KMS_Agent__ListKeyGroups(
1386 pstSoap,
1387 sURL,
1388 NULL,
1389 oQueryParameters,
1390 oResponse) == SOAP_OK;
1391
1392 if (!bSuccess)
1393 {
1394 iIndex = pLoadBalancer->FailOver(iIndex, pstSoap);
1395
1396 char sKmaAddress[g_iMAX_PEER_NETWORK_ADDRESS_LENGTH];
1397 char sSoapFaultMsg[g_iMAX_SOAP_FAULT_MESSAGE_LENGTH];
1398
1399 GetPeerNetworkAddress(sKmaAddress, pstSoap);
1400 GetSoapFault(sSoapFaultMsg, pstSoap);
1401
1402 LogError(i_pProfile, AUDIT_CLIENT_AGENT_LIST_KEY_GROUPS_SOAP_ERROR,
1403 NULL,
1404 sKmaAddress,
1405 sSoapFaultMsg);
1406 }
1407 else
1408 {
1409 pLoadBalancer->UpdateResponseStatus(iIndex);
1410 }
1411 }
1412 while (iIndex >= 0 && (!bSuccess));
1413 }
1414 else
1415 {
1416 bSuccess = false;
1417 }
1418
1419 if (bSuccess)
1420 {
1421 bIsLastPage = oResponse.LastPage;
1422
1423 *o_ppKeyGroups = CopyKeyGroupsResponse(&oResponse.KeyGroups);
1424 if (*o_ppKeyGroups == NULL)
1425 {
1426 bSuccess = false;
1427 // no memory, don't log
1428 }
1429
1430 CopyQueryParametersFromResponse(&stQueryParameters,
1431 &oResponse.NextPageQueryParameters);
1432 }
1433
1434 // free allocated memory for output if error condition
1435 // Clean up SOAP
1436
1437 soap_destroy(pstSoap);
1438 soap_end(pstSoap);
1439
1440 if (bSuccess)
1441 RETURN(KMS_AGENT_STATUS_OK);
1442
1443 RETURN(KMSAgent_GetLastStatusCode(i_pProfile, iIndex));
1444 }
1445
1446 /*---------------------------------------------------------------------------
1447 * Function: KMSAgent_FreeArrayOfKeyGroups
1448 *
1449 *--------------------------------------------------------------------------*/
1450
1451 extern "C"
KMSAgent_FreeArrayOfKeyGroups(struct KMSAgent_ArrayOfKeyGroups * i_pArrayOfKeyGroups)1452 void KMSAgent_FreeArrayOfKeyGroups (
1453 struct KMSAgent_ArrayOfKeyGroups *i_pArrayOfKeyGroups)
1454 {
1455 #if defined(METAWARE)
1456 ECPT_TRACE_ENTRY *trace = NULL;
1457 ECPT_TRACE(trace, KMSAgent_FreeArrayOfKeyGroups);
1458 #endif
1459 if (!i_pArrayOfKeyGroups)
1460 {
1461 return;
1462 }
1463
1464 // free memory for all information groups
1465 if (i_pArrayOfKeyGroups->m_pKeyGroups)
1466 {
1467 free(i_pArrayOfKeyGroups->m_pKeyGroups);
1468 }
1469
1470 free(i_pArrayOfKeyGroups);
1471 }
1472
1473 extern "C"
KMSAgent_CreateKey(KMSClientProfile * const i_pProfile,const KMSAgent_DataUnit * const i_pDataUnit,KEY_GROUP_ID const i_pKeyGroupID,KMSAgent_Key * const o_pKey)1474 KMS_AGENT_STATUS KMSAgent_CreateKey (
1475 KMSClientProfile * const i_pProfile,
1476 const KMSAgent_DataUnit * const i_pDataUnit,
1477 KEY_GROUP_ID const i_pKeyGroupID,
1478 KMSAgent_Key * const o_pKey)
1479 {
1480 bool bSuccess;
1481 #if defined(METAWARE)
1482 ECPT_TRACE_ENTRY *trace = NULL;
1483 ECPT_TRACE(trace, KMSAgent_CreateKey);
1484 #endif
1485
1486 if (!i_pProfile)
1487 {
1488 Log(AUDIT_CLIENT_AGENT_CREATE_KEY_INVALID_PARAMETERS,
1489 NULL,
1490 NULL,
1491 "Profile arg");
1492 RETURN(KMS_AGENT_STATUS_INVALID_PARAMETER);
1493 }
1494 if (!o_pKey)
1495 {
1496 Log(AUDIT_CLIENT_AGENT_CREATE_KEY_INVALID_PARAMETERS,
1497 NULL,
1498 NULL,
1499 "Key arg");
1500 RETURN(KMS_AGENT_STATUS_INVALID_PARAMETER);
1501 }
1502
1503 if (!KMSClient_ProfileLoaded(i_pProfile))
1504 {
1505 RETURN(KMS_AGENT_STATUS_PROFILE_NOT_LOADED);
1506 }
1507
1508 if (i_pKeyGroupID &&
1509 strlen(i_pKeyGroupID) > KMS_MAX_KEY_GROUP_ID_SIZE)
1510 {
1511 Log(AUDIT_CLIENT_AGENT_CREATE_KEY_INVALID_PARAMETERS,
1512 NULL,
1513 NULL,
1514 "GroupID arg");
1515 RETURN(KMS_AGENT_STATUS_INVALID_PARAMETER);
1516 }
1517
1518 CAutoMutex oAutoMutex((K_MUTEX_HANDLE) i_pProfile->m_pLock);
1519
1520 struct KMS_Agent::KMS_Agent__DataUnit
1521 stDataUnit = {"", "", "", "",
1522 (KMS_Agent::KMS_Agent__DataUnitState) 0};
1523
1524 struct soap *pstSoap = (struct soap *) i_pProfile->m_pvSoap;
1525 struct KMS_Agent::KMS_Agent__CreateKeyResponse oResponse;
1526
1527 if (i_pDataUnit != NULL)
1528 {
1529 if (!CopyDataUnitFromRequest(pstSoap,
1530 &stDataUnit,
1531 i_pDataUnit))
1532 {
1533 soap_destroy(pstSoap);
1534 soap_end(pstSoap);
1535 // no memory dont' log
1536 RETURN(KMS_AGENT_STATUS_NO_MEMORY);
1537 }
1538 }
1539
1540 char * pKeyGroupID = NULL;
1541 if (i_pKeyGroupID)
1542 {
1543 pKeyGroupID = ConvertUTF8StringFromRequest(pstSoap,
1544 i_pKeyGroupID,
1545 KMS_MAX_KEY_GROUP_ID_SIZE + 1);
1546 if (pKeyGroupID == NULL)
1547 {
1548 soap_destroy(pstSoap);
1549 soap_end(pstSoap);
1550 // no memory dont' log
1551 RETURN(KMS_AGENT_STATUS_NO_MEMORY);
1552 }
1553 }
1554
1555 CAgentLoadBalancer *pLoadBalancer =
1556 (CAgentLoadBalancer *) i_pProfile->m_pAgentLoadBalancer;
1557
1558 char sKmaAddress[g_iMAX_PEER_NETWORK_ADDRESS_LENGTH];
1559 char sSoapFaultMsg[g_iMAX_SOAP_FAULT_MESSAGE_LENGTH];
1560
1561 int iIndex;
1562 UTF8_KEYID acKWKID;
1563 bool bClientAESKeyWrapSetupError = false;
1564
1565 if (i_pDataUnit)
1566 {
1567 // attempt to maintain affinity with KMA for specified DU ID
1568 iIndex = pLoadBalancer->BalanceByDataUnitID(
1569 i_pDataUnit->m_acDataUnitID,
1570 KMS_DATA_UNIT_ID_SIZE);
1571 }
1572 else
1573 {
1574 iIndex = pLoadBalancer->Balance();
1575 }
1576
1577 if (iIndex >= 0)
1578 {
1579 do
1580 {
1581 bSuccess = true;
1582 const char* sURL = pLoadBalancer->GetHTTPSURL(
1583 iIndex,
1584 i_pProfile->m_iPortForAgentService);
1585
1586 strncpy(i_pProfile->m_sURL, sURL, sizeof(i_pProfile->m_sURL));
1587
1588 i_pProfile->m_sURL[sizeof(i_pProfile->m_sURL)-1] = '\0';
1589
1590 Long64 lKMAID = pLoadBalancer->GetKMAID(iIndex);
1591
1592 if (bSuccess && pLoadBalancer->AESKeyWrapSupported(iIndex))
1593 {
1594 // if this fails we want to utilize normal failover logic, GetKWKID
1595 // logs error
1596 bSuccess = pLoadBalancer->GetKWKID(iIndex, lKMAID, pstSoap,
1597 acKWKID, &bClientAESKeyWrapSetupError) ? true : false;
1598 if (bSuccess)
1599 {
1600 bSuccess = KMS_Agent::soap_call_KMS_Agent__CreateKey2(
1601 pstSoap,
1602 sURL,
1603 NULL,
1604 stDataUnit,
1605 i_pKeyGroupID ? pKeyGroupID : (char *) "",
1606 acKWKID,
1607 //NOTE: this is ugly but the soap response struct's are the same for both flavors of CreateKey
1608 *(reinterpret_cast<struct KMS_Agent::KMS_Agent__CreateKey2Response *>(&oResponse))) == SOAP_OK;
1609 }
1610 }
1611 else if (bSuccess) // NO AES Key Wrap
1612 {
1613 bSuccess = KMS_Agent::soap_call_KMS_Agent__CreateKey(
1614 pstSoap,
1615 sURL,
1616 NULL,
1617 stDataUnit,
1618 i_pKeyGroupID ? pKeyGroupID : (char *) "",
1619 oResponse) == SOAP_OK;
1620 }
1621
1622 // don'f failover for Client side AES Key Wrap setup problems
1623 if (!bSuccess && !bClientAESKeyWrapSetupError)
1624 {
1625 iIndex = pLoadBalancer->FailOver(iIndex, pstSoap);
1626
1627 GetPeerNetworkAddress(sKmaAddress, pstSoap);
1628 GetSoapFault(sSoapFaultMsg, pstSoap);
1629
1630 LogError(i_pProfile,
1631 AUDIT_CLIENT_AGENT_CREATE_KEY_SOAP_ERROR,
1632 NULL,
1633 sKmaAddress,
1634 sSoapFaultMsg);
1635 }
1636 if (bSuccess)
1637 {
1638 pLoadBalancer->UpdateResponseStatus(iIndex);
1639 }
1640 }
1641 while (iIndex >= 0 && (!bSuccess) && (!bClientAESKeyWrapSetupError));
1642 }
1643 else
1644 {
1645 bSuccess = false;
1646 }
1647
1648
1649 #if defined(DEBUG) && defined(METAWARE)
1650 log_printf("CreateKey gets keyID %s (size %x) \n",
1651 oResponse.Key.KeyID,
1652 sizeof (oResponse.Key.KeyID));
1653 #endif
1654
1655
1656 if (bSuccess)
1657 {
1658 if (KMS_KEY_ID_SIZE != ConvertUTF8HexStringToBinary(
1659 oResponse.Key.KeyID, NULL))
1660 {
1661 GetPeerNetworkAddress(sKmaAddress, pstSoap);
1662 LogError(i_pProfile,
1663 AUDIT_CLIENT_AGENT_CREATE_KEY_INVALID_KEYID_RESPONSE,
1664 NULL,
1665 sKmaAddress,
1666 NULL);
1667 bSuccess = false;
1668 }
1669
1670 ConvertUTF8HexStringToBinary(
1671 oResponse.Key.KeyID, // in
1672 o_pKey->m_acKeyID); // out
1673
1674 #if defined(DEBUG) && defined(METAWARE)
1675 log_printf("CreateKey gets keyState %x (size %x) \n",
1676 oResponse.Key.KeyState,
1677 sizeof (oResponse.Key.KeyState));
1678 #endif
1679
1680 if ((KMS_AGENT_KEY_STATE) oResponse.Key.KeyState < KMS_KEY_STATE_ACTIVE_PROTECT_AND_PROCESS ||
1681 (KMS_AGENT_KEY_STATE) oResponse.Key.KeyState > KMS_KEY_STATE_COMPROMISED)
1682 {
1683 GetPeerNetworkAddress(sKmaAddress, pstSoap);
1684 LogError(i_pProfile,
1685 AUDIT_CLIENT_AGENT_CREATE_KEY_INVALID_KEY_STATE_RESPONSE,
1686 NULL,
1687 sKmaAddress,
1688 NULL);
1689 bSuccess = false;
1690 }
1691
1692 o_pKey->m_iKeyState = (KMS_AGENT_KEY_STATE) oResponse.Key.KeyState;
1693
1694 #if defined(DEBUG) && defined(METAWARE)
1695 log_printf("CreateKey o_pKey->m_iKeyState %x (size %x) = "
1696 "(KMS_AGENT_KEY_STATE) oResponse.Key.KeyState %x (size %x)\n",
1697 o_pKey->m_iKeyState,
1698 sizeof (o_pKey->m_iKeyState),
1699 oResponse.Key.KeyState,
1700 sizeof (oResponse.Key.KeyState));
1701 #endif
1702
1703
1704 if ((KMS_KEY_TYPE) oResponse.Key.KeyType != KMS_KEY_TYPE_AES_256)
1705 {
1706 GetPeerNetworkAddress(sKmaAddress, pstSoap);
1707 LogError(i_pProfile,
1708 AUDIT_CLIENT_AGENT_CREATE_KEY_INVALID_KEY_TYPE_RESPONSE,
1709 NULL,
1710 sKmaAddress,
1711 NULL);
1712 bSuccess = false;
1713 }
1714 o_pKey->m_iKeyType = (KMS_KEY_TYPE) oResponse.Key.KeyType;
1715
1716 if (strlen(oResponse.Key.KeyGroupID) > KMS_MAX_KEY_GROUP_ID_SIZE)
1717 {
1718 GetPeerNetworkAddress(sKmaAddress, pstSoap);
1719 LogError(i_pProfile,
1720 AUDIT_CLIENT_AGENT_CREATE_KEY_INVALID_KEY_GROUP_ID_LENGTH_RESPONSE,
1721 NULL,
1722 sKmaAddress,
1723 NULL);
1724 bSuccess = false;
1725 }
1726 else
1727 {
1728 strncpy(o_pKey->m_acKeyGroupID,
1729 oResponse.Key.KeyGroupID,
1730 sizeof(o_pKey->m_acKeyGroupID));
1731 o_pKey->m_acKeyGroupID[sizeof(o_pKey->m_acKeyGroupID)-1] = '\0';
1732 }
1733
1734 if ( bSuccess && pLoadBalancer->AESKeyWrapSupported(iIndex))
1735 {
1736 // verify KWK ID matches what was registered
1737 if (oResponse.Key.Key.__size != KMS_MAX_WRAPPED_KEY_SIZE)
1738 {
1739 GetPeerNetworkAddress(sKmaAddress, pstSoap);
1740 LogError(i_pProfile,
1741 AUDIT_CLIENT_AGENT_CREATE_KEY_INVALID_WRAPPED_KEY_LENGTH_RESPONSE,
1742 NULL,
1743 sKmaAddress,
1744 NULL);
1745 bSuccess = false;
1746 }
1747 else
1748 {
1749 if (pLoadBalancer->AESKeyUnwrap(&iIndex, oResponse.Key.Key.__ptr,
1750 o_pKey->m_acKey) == false)
1751 {
1752 GetPeerNetworkAddress(sKmaAddress, pstSoap);
1753 LogError(i_pProfile,
1754 AUDIT_CLIENT_AGENT_CREATE_KEY_AESKEYUNWRAP_ERROR,
1755 NULL,
1756 sKmaAddress,
1757 NULL);
1758
1759 bSuccess = false;
1760 }
1761 }
1762 }
1763 else if (bSuccess) // non-AES key wrap
1764 {
1765 if (oResponse.Key.Key.__size != KMS_MAX_KEY_SIZE)
1766 {
1767 GetPeerNetworkAddress(sKmaAddress, pstSoap);
1768 LogError(i_pProfile,
1769 AUDIT_CLIENT_AGENT_CREATE_KEY_INVALID_KEY_LENGTH_RESPONSE,
1770 NULL,
1771 sKmaAddress,
1772 NULL);
1773 bSuccess = false;
1774 }
1775 else
1776 {
1777 memcpy(o_pKey->m_acKey,
1778 oResponse.Key.Key.__ptr,
1779 KMS_MAX_KEY_SIZE);
1780 }
1781 }
1782
1783 if (bSuccess)
1784 {
1785 o_pKey->m_iKeyLength = KMS_MAX_KEY_SIZE;
1786
1787 if (KMSAgentKeyCallout(o_pKey->m_acKey) != 0)
1788 {
1789 LogError(i_pProfile,
1790 AUDIT_CLIENT_AGENT_CREATE_KEY_KEY_CALLOUT_ERROR,
1791 NULL,
1792 NULL,
1793 NULL);
1794 bSuccess = false;
1795 }
1796 }
1797 }
1798
1799 if (bSuccess)
1800 {
1801 // add Key ID and the creating KMA IP address to the DU cache
1802 CDataUnitCache* pDataUnitCache = (CDataUnitCache*) i_pProfile->m_pDataUnitCache;
1803
1804 if (i_pProfile->m_iClusterDiscoveryFrequency != 0) // load balancing enabled
1805 {
1806 bSuccess = pDataUnitCache->Insert(
1807 NULL,
1808 0,
1809 o_pKey->m_acKeyID,
1810 KMS_KEY_ID_SIZE,
1811 pLoadBalancer->GetApplianceNetworkAddress(iIndex));
1812 }
1813 }
1814 // free allocated memory for output if error condition
1815 // Clean up SOAP
1816
1817 soap_destroy(pstSoap);
1818 soap_end(pstSoap);
1819
1820 if (bSuccess)
1821 {
1822 RETURN(KMS_AGENT_STATUS_OK);
1823 }
1824
1825 RETURN(KMSAgent_GetLastStatusCode(i_pProfile,
1826 bClientAESKeyWrapSetupError ?
1827 CAgentLoadBalancer::AES_KEY_WRAP_SETUP_ERROR : iIndex));
1828 }
1829
1830 extern "C"
KMSAgent_CreateDataUnit(KMSClientProfile * const i_pProfile,const unsigned char * i_pExternalUniqueID,int i_iExternalUniqueIDIDLen,utf8cstr const i_pExternalTag,utf8cstr const i_pDescription,KMSAgent_DataUnit * const o_pDataUnit)1831 KMS_AGENT_STATUS KMSAgent_CreateDataUnit (
1832 KMSClientProfile * const i_pProfile,
1833 const unsigned char * i_pExternalUniqueID,
1834 int i_iExternalUniqueIDIDLen,
1835 utf8cstr const i_pExternalTag,
1836 utf8cstr const i_pDescription,
1837 KMSAgent_DataUnit * const o_pDataUnit)
1838 {
1839 bool bSuccess;
1840 #if defined(METAWARE)
1841 ECPT_TRACE_ENTRY *trace = NULL;
1842 ECPT_TRACE(trace, KMSAgent_CreateDataUnit);
1843 #endif
1844
1845 #if defined(DEBUG) && defined(METAWARE)
1846 #warn "debug Create Data Unit is on"
1847 log_printf("KMSAgent_CreateDataUnit entered\n");
1848 log_printf("KMSAgent_CreateDataUnit profile=%x\n", i_pProfile);
1849 #endif
1850
1851 if (!i_pProfile)
1852 {
1853 Log(AUDIT_CLIENT_AGENT_CREATE_DATA_UNIT_INVALID_PARAMETERS,
1854 NULL,
1855 NULL,
1856 "Profile arg");
1857 RETURN(KMS_AGENT_STATUS_INVALID_PARAMETER);
1858 }
1859 if (!o_pDataUnit)
1860 {
1861 Log(AUDIT_CLIENT_AGENT_CREATE_DATA_UNIT_INVALID_PARAMETERS,
1862 NULL,
1863 NULL,
1864 "DataUnit arg");
1865 RETURN(KMS_AGENT_STATUS_INVALID_PARAMETER);
1866 }
1867
1868 if (!KMSClient_ProfileLoaded(i_pProfile))
1869 {
1870 RETURN(KMS_AGENT_STATUS_PROFILE_NOT_LOADED);
1871 }
1872
1873 CAutoMutex oAutoMutex((K_MUTEX_HANDLE) i_pProfile->m_pLock);
1874
1875 // validate input parms
1876
1877 if (i_pExternalUniqueID &&
1878 (i_iExternalUniqueIDIDLen <= 0 ||
1879 i_iExternalUniqueIDIDLen > KMS_MAX_EXTERNAL_UNIQUE_ID_SIZE))
1880 {
1881 Log(AUDIT_CLIENT_AGENT_CREATE_DATA_UNIT_INVALID_PARAMETERS,
1882 NULL,
1883 NULL,
1884 "ExternalUniqueID arg");
1885 RETURN(KMS_AGENT_STATUS_INVALID_PARAMETER);
1886 }
1887
1888 if (i_pExternalTag && strlen(i_pExternalTag) > KMS_MAX_EXTERNAL_TAG)
1889 {
1890 RETURN(KMS_AGENT_STATUS_INVALID_PARAMETER);
1891 }
1892
1893 if (i_pDescription && strlen(i_pDescription) > KMS_MAX_DESCRIPTION)
1894 {
1895 RETURN(KMS_AGENT_STATUS_INVALID_PARAMETER);
1896 }
1897
1898 struct soap *pstSoap = (struct soap *) i_pProfile->m_pvSoap;
1899 struct KMS_Agent::KMS_Agent__CreateDataUnitResponse oResponse;
1900
1901 char * pExternalUniqueID = NULL;
1902 if (i_pExternalUniqueID)
1903 {
1904 pExternalUniqueID = ConvertBinaryDataFromRequest(pstSoap,
1905 i_pExternalUniqueID,
1906 i_iExternalUniqueIDIDLen);
1907 if (pExternalUniqueID == NULL)
1908 {
1909 soap_destroy(pstSoap);
1910 soap_end(pstSoap);
1911 // no memory dont' log
1912 RETURN(KMS_AGENT_STATUS_NO_MEMORY);
1913 }
1914 }
1915
1916 char * pExternalTag = NULL;
1917 if (i_pExternalTag)
1918 {
1919 pExternalTag = ConvertUTF8StringFromRequest(pstSoap,
1920 i_pExternalTag,
1921 strlen(i_pExternalTag) + 1);
1922 if (pExternalTag == NULL)
1923 {
1924 soap_destroy(pstSoap);
1925 soap_end(pstSoap);
1926 // no memory dont' log
1927 RETURN(KMS_AGENT_STATUS_NO_MEMORY);
1928 }
1929 }
1930
1931 char * pDescription = NULL;
1932 if (i_pDescription)
1933 {
1934 pDescription = ConvertUTF8StringFromRequest(pstSoap,
1935 i_pDescription,
1936 strlen(i_pDescription) + 1);
1937 if (pDescription == NULL)
1938 {
1939 soap_destroy(pstSoap);
1940 soap_end(pstSoap);
1941 // no memory dont' log
1942 RETURN(KMS_AGENT_STATUS_NO_MEMORY);
1943 }
1944 }
1945
1946 CAgentLoadBalancer *pLoadBalancer =
1947 (CAgentLoadBalancer *) i_pProfile->m_pAgentLoadBalancer;
1948 int iIndex = pLoadBalancer->Balance();
1949
1950 if (iIndex >= 0)
1951 {
1952 do
1953 {
1954 const char* sURL = pLoadBalancer->GetHTTPSURL(
1955 iIndex,
1956 i_pProfile->m_iPortForAgentService);
1957
1958 strncpy(i_pProfile->m_sURL, sURL, sizeof(i_pProfile->m_sURL));
1959
1960 i_pProfile->m_sURL[sizeof(i_pProfile->m_sURL)-1] = '\0';
1961
1962 bSuccess = KMS_Agent::soap_call_KMS_Agent__CreateDataUnit(
1963 pstSoap,
1964 sURL,
1965 NULL,
1966 i_pExternalUniqueID ? pExternalUniqueID : (char *) "",
1967 i_pExternalTag ? pExternalTag : (char *) "",
1968 i_pDescription ? pDescription : (char *) "",
1969 oResponse) == SOAP_OK;
1970
1971 if (!bSuccess)
1972 {
1973 iIndex = pLoadBalancer->FailOver(iIndex, pstSoap);
1974
1975 char sKmaAddress[g_iMAX_PEER_NETWORK_ADDRESS_LENGTH];
1976 char sSoapFaultMsg[g_iMAX_SOAP_FAULT_MESSAGE_LENGTH];
1977
1978 GetPeerNetworkAddress(sKmaAddress, pstSoap);
1979 GetSoapFault(sSoapFaultMsg, pstSoap);
1980
1981 LogError(i_pProfile,
1982 AUDIT_CLIENT_AGENT_CREATE_DATA_UNIT_SOAP_ERROR,
1983 NULL,
1984 sKmaAddress,
1985 sSoapFaultMsg);
1986 }
1987 else
1988 {
1989 pLoadBalancer->UpdateResponseStatus(iIndex);
1990 }
1991
1992 }
1993 while (iIndex >= 0 && (!bSuccess));
1994 }
1995 else
1996 {
1997 bSuccess = false;
1998 }
1999
2000 if (bSuccess)
2001 {
2002 int iDataUnitIDLength;
2003 iDataUnitIDLength = ConvertUTF8HexStringToBinary(
2004 oResponse.DataUnit.DataUnitID, o_pDataUnit->m_acDataUnitID);
2005
2006 if (iDataUnitIDLength != KMS_DATA_UNIT_ID_SIZE)
2007 {
2008 #if defined(DEBUG) && defined(METAWARE)
2009 log_printf("iDataUnitIDLength (%x) != KMS_DATA_UNIT_ID_SIZE (%x)",
2010 iDataUnitIDLength,
2011 KMS_DATA_UNIT_ID_SIZE);
2012 #endif
2013 LogError(i_pProfile,
2014 AUDIT_CLIENT_AGENT_CREATE_DATA_UNIT_RESPONSE_INVALID_DU_ID_LENGTH,
2015 NULL,
2016 NULL,
2017 NULL);
2018 bSuccess = false;
2019 }
2020 o_pDataUnit->m_iExternalUniqueIDLength = ConvertUTF8HexStringToBinary(
2021 oResponse.DataUnit.ExternalUniqueID, o_pDataUnit->m_acExternalUniqueID);
2022
2023 if (strlen(oResponse.DataUnit.ExternalTag) > KMS_MAX_EXTERNAL_TAG)
2024 {
2025 LogError(i_pProfile,
2026 AUDIT_CLIENT_AGENT_CREATE_DATA_UNIT_RESPONSE_INVALID_EXTERNAL_TAG_LENGTH,
2027 NULL,
2028 NULL,
2029 NULL);
2030 bSuccess = false;
2031 }
2032 else
2033 {
2034 strncpy(o_pDataUnit->m_acExternalTag,
2035 oResponse.DataUnit.ExternalTag,
2036 sizeof(o_pDataUnit->m_acExternalTag));
2037 o_pDataUnit->m_acExternalTag[sizeof(o_pDataUnit->m_acExternalTag)-1] = '\0';
2038 }
2039
2040 if (strlen(oResponse.DataUnit.Description) > KMS_MAX_DESCRIPTION)
2041 {
2042 LogError(i_pProfile,
2043 AUDIT_CLIENT_AGENT_CREATE_DATA_UNIT_RESPONSE_INVALID_DESCRIPTION_LENGTH,
2044 NULL,
2045 NULL,
2046 NULL);
2047 bSuccess = false;
2048 }
2049 else
2050 {
2051 strcpy(o_pDataUnit->m_acDescription,
2052 oResponse.DataUnit.Description);
2053 }
2054
2055 o_pDataUnit->m_iDataUnitState =
2056 (KMS_AGENT_DATA_UNIT_STATE) oResponse.DataUnit.DataUnitState;
2057 }
2058
2059 if (bSuccess)
2060 {
2061 // add data unit ID and the creating KMA IP address to the DU cache
2062 CDataUnitCache* pDataUnitCache = (CDataUnitCache*) i_pProfile->m_pDataUnitCache;
2063
2064 if (i_pProfile->m_iClusterDiscoveryFrequency != 0) // load balancing enabled
2065 {
2066 bSuccess = pDataUnitCache->Insert(
2067 o_pDataUnit->m_acDataUnitID,
2068 KMS_DATA_UNIT_ID_SIZE,
2069 NULL, 0,
2070 pLoadBalancer->GetApplianceNetworkAddress(iIndex));
2071 }
2072 }
2073
2074 // free allocated memory for output if error condition
2075 // Clean up SOAP
2076
2077 soap_destroy(pstSoap);
2078 soap_end(pstSoap);
2079
2080 if (bSuccess)
2081 {
2082 RETURN(KMS_AGENT_STATUS_OK);
2083 }
2084
2085 RETURN(KMSAgent_GetLastStatusCode(i_pProfile, iIndex));
2086 }
2087
2088 extern "C"
KMSAgent_DisassociateDataUnitKeys(KMSClientProfile * const i_pProfile,const KMSAgent_DataUnit * const i_pDataUnit)2089 KMS_AGENT_STATUS KMSAgent_DisassociateDataUnitKeys (
2090 KMSClientProfile * const i_pProfile,
2091 const KMSAgent_DataUnit * const i_pDataUnit)
2092 {
2093 bool bSuccess;
2094 #if defined(METAWARE)
2095 ECPT_TRACE_ENTRY *trace = NULL;
2096 ECPT_TRACE(trace, KMSAgent_DisassociateDataUnitKeys);
2097 #endif
2098
2099 if (!i_pProfile)
2100 {
2101 Log(AUDIT_CLIENT_AGENT_DISASSOCIATE_DATA_UNIT_KEYS_INVALID_PARAMETERS,
2102 NULL,
2103 NULL,
2104 "Profile arg");
2105 RETURN(KMS_AGENT_STATUS_INVALID_PARAMETER);
2106 }
2107
2108 if (!i_pDataUnit)
2109 {
2110 Log(AUDIT_CLIENT_AGENT_DISASSOCIATE_DATA_UNIT_KEYS_INVALID_PARAMETERS,
2111 NULL,
2112 NULL,
2113 "DataUnit arg");
2114 RETURN(KMS_AGENT_STATUS_INVALID_PARAMETER);
2115 }
2116 if (!KMSClient_ProfileLoaded(i_pProfile))
2117 {
2118 RETURN(KMS_AGENT_STATUS_PROFILE_NOT_LOADED);
2119 }
2120
2121 CAutoMutex oAutoMutex((K_MUTEX_HANDLE) i_pProfile->m_pLock);
2122
2123 struct KMS_Agent::KMS_Agent__DataUnit stDataUnit = {"", "", "", "",
2124 (KMS_Agent::KMS_Agent__DataUnitState) 0};
2125
2126 struct soap *pstSoap = (struct soap *) i_pProfile->m_pvSoap;
2127 struct KMS_Agent::KMS_Agent__DisassociateDataUnitKeysResponse oResponse;
2128
2129 if (!CopyDataUnitFromRequest(pstSoap,
2130 &stDataUnit,
2131 i_pDataUnit))
2132 {
2133 soap_destroy(pstSoap);
2134 soap_end(pstSoap);
2135 // no memory dont' log
2136 RETURN(KMS_AGENT_STATUS_NO_MEMORY);
2137 }
2138
2139 CAgentLoadBalancer *pLoadBalancer =
2140 (CAgentLoadBalancer *) i_pProfile->m_pAgentLoadBalancer;
2141 int iIndex = pLoadBalancer->BalanceByDataUnitID(
2142 i_pDataUnit->m_acDataUnitID,
2143 KMS_DATA_UNIT_ID_SIZE);
2144
2145 if (iIndex >= 0)
2146 {
2147 do
2148 {
2149 const char* sURL = pLoadBalancer->GetHTTPSURL(
2150 iIndex,
2151 i_pProfile->m_iPortForAgentService);
2152
2153 strncpy(i_pProfile->m_sURL, sURL, sizeof(i_pProfile->m_sURL));
2154
2155 i_pProfile->m_sURL[sizeof(i_pProfile->m_sURL)-1] = '\0';
2156
2157 bSuccess = KMS_Agent::soap_call_KMS_Agent__DisassociateDataUnitKeys(
2158 pstSoap,
2159 sURL,
2160 NULL,
2161 stDataUnit,
2162 oResponse) == SOAP_OK;
2163
2164 if (!bSuccess)
2165 {
2166 iIndex = pLoadBalancer->FailOver(iIndex, pstSoap);
2167
2168 char sKmaAddress[g_iMAX_PEER_NETWORK_ADDRESS_LENGTH];
2169 char sSoapFaultMsg[g_iMAX_SOAP_FAULT_MESSAGE_LENGTH];
2170
2171 GetPeerNetworkAddress(sKmaAddress, pstSoap);
2172 GetSoapFault(sSoapFaultMsg, pstSoap);
2173
2174 LogError(i_pProfile,
2175 AUDIT_CLIENT_AGENT_DISASSOCIATE_DATA_UNIT_KEYS_SOAP_ERROR,
2176 NULL,
2177 sKmaAddress,
2178 sSoapFaultMsg);
2179 }
2180 else
2181 {
2182 pLoadBalancer->UpdateResponseStatus(iIndex);
2183 }
2184 }
2185 while (iIndex >= 0 && (!bSuccess));
2186 }
2187 else
2188 {
2189 bSuccess = false;
2190 }
2191
2192 // no response data for this transaction
2193
2194 // free allocated memory for output if error condition
2195 // Clean up SOAP
2196
2197 soap_destroy(pstSoap);
2198 soap_end(pstSoap);
2199
2200 if (bSuccess)
2201 {
2202 RETURN(KMS_AGENT_STATUS_OK);
2203 }
2204
2205 RETURN(KMSAgent_GetLastStatusCode(i_pProfile, iIndex));
2206 }
2207
2208 extern "C"
KMSAgent_RetrieveKey(KMSClientProfile * const i_pProfile,const unsigned char * const i_pKeyID,const KMSAgent_DataUnit * const i_pDataUnit,utf8cstr const i_pKeyGroupID,KMSAgent_Key * const o_pKey)2209 KMS_AGENT_STATUS KMSAgent_RetrieveKey (
2210 KMSClientProfile * const i_pProfile,
2211 const unsigned char * const i_pKeyID,
2212 const KMSAgent_DataUnit * const i_pDataUnit,
2213 utf8cstr const i_pKeyGroupID,
2214 KMSAgent_Key * const o_pKey)
2215 {
2216 bool bSuccess;
2217
2218 #if defined(METAWARE)
2219 ECPT_TRACE_ENTRY *trace = NULL;
2220 ECPT_TRACE(trace, KMSAgent_RetrieveKey);
2221 #endif
2222
2223 if (!i_pProfile)
2224 {
2225 Log(AUDIT_CLIENT_AGENT_RETRIEVE_KEY_INVALID_PARAMETERS,
2226 NULL,
2227 NULL,
2228 "Profile arg");
2229 RETURN(KMS_AGENT_STATUS_INVALID_PARAMETER);
2230 }
2231 if (!i_pKeyID)
2232 {
2233 Log(AUDIT_CLIENT_AGENT_RETRIEVE_KEY_INVALID_PARAMETERS,
2234 NULL,
2235 NULL,
2236 "KeyID arg");
2237 RETURN(KMS_AGENT_STATUS_INVALID_PARAMETER);
2238 }
2239 if (!o_pKey)
2240 {
2241 Log(AUDIT_CLIENT_AGENT_RETRIEVE_KEY_INVALID_PARAMETERS,
2242 NULL,
2243 NULL,
2244 "Key arg");
2245 RETURN(KMS_AGENT_STATUS_INVALID_PARAMETER);
2246 }
2247
2248 if (!KMSClient_ProfileLoaded(i_pProfile))
2249 {
2250 RETURN(KMS_AGENT_STATUS_PROFILE_NOT_LOADED);
2251 }
2252
2253 CAutoMutex oAutoMutex((K_MUTEX_HANDLE) i_pProfile->m_pLock);
2254
2255 if (i_pKeyGroupID &&
2256 strlen(i_pKeyGroupID) > KMS_MAX_KEY_GROUP_ID_SIZE)
2257 {
2258 Log(AUDIT_CLIENT_AGENT_RETRIEVE_KEY_INVALID_PARAMETERS,
2259 NULL,
2260 NULL,
2261 "GroupID arg");
2262 RETURN(KMS_AGENT_STATUS_INVALID_PARAMETER);
2263 }
2264
2265 struct KMS_Agent::KMS_Agent__DataUnit stDataUnit = {"", "", "", "",
2266 (KMS_Agent::KMS_Agent__DataUnitState) 0};
2267
2268 struct soap *pstSoap = (struct soap *) i_pProfile->m_pvSoap;
2269 struct KMS_Agent::KMS_Agent__RetrieveKeyResponse oResponse;
2270
2271 char * pKeyID = NULL;
2272 pKeyID = ConvertBinaryDataFromRequest(pstSoap,
2273 i_pKeyID,
2274 KMS_KEY_ID_SIZE);
2275 if (pKeyID == NULL)
2276 {
2277 soap_destroy(pstSoap);
2278 soap_end(pstSoap);
2279 // no memory dont' log
2280 RETURN(KMS_AGENT_STATUS_NO_MEMORY);
2281 }
2282
2283 if (i_pDataUnit != NULL)
2284 {
2285 if (!CopyDataUnitFromRequest(pstSoap,
2286 &stDataUnit,
2287 i_pDataUnit))
2288 {
2289 soap_destroy(pstSoap);
2290 soap_end(pstSoap);
2291 // no memory dont' log
2292 RETURN(KMS_AGENT_STATUS_NO_MEMORY);
2293 }
2294 }
2295
2296 char * pKeyGroupID = NULL;
2297 if (i_pKeyGroupID)
2298 {
2299 pKeyGroupID = ConvertUTF8StringFromRequest(pstSoap,
2300 i_pKeyGroupID,
2301 KMS_MAX_KEY_GROUP_ID_SIZE + 1);
2302 if (pKeyGroupID == NULL)
2303 {
2304 soap_destroy(pstSoap);
2305 soap_end(pstSoap);
2306 // no memory dont' log
2307 RETURN(KMS_AGENT_STATUS_NO_MEMORY);
2308 }
2309 }
2310
2311 UTF8_KEYID acKWKID;
2312
2313 char sKmaAddress[g_iMAX_PEER_NETWORK_ADDRESS_LENGTH];
2314 char sSoapFaultMsg[g_iMAX_SOAP_FAULT_MESSAGE_LENGTH];
2315 bool bClientAESKeyWrapSetupError = false;
2316
2317 CAgentLoadBalancer *pLoadBalancer =
2318 (CAgentLoadBalancer *) i_pProfile->m_pAgentLoadBalancer;
2319 int iIndex = pLoadBalancer->BalanceByDataUnitKeyID(i_pKeyID, KMS_KEY_ID_SIZE);
2320
2321 if (iIndex >= 0)
2322 {
2323 do
2324 {
2325 bSuccess = true;
2326 const char* sURL = pLoadBalancer->GetHTTPSURL(
2327 iIndex,
2328 i_pProfile->m_iPortForAgentService);
2329
2330 strncpy(i_pProfile->m_sURL, sURL, sizeof(i_pProfile->m_sURL));
2331
2332 i_pProfile->m_sURL[sizeof(i_pProfile->m_sURL)-1] = '\0';
2333
2334 Long64 lKMAID = pLoadBalancer->GetKMAID(iIndex);
2335
2336 if (bSuccess && pLoadBalancer->AESKeyWrapSupported(iIndex))
2337 {
2338 // if this fails we want to utilize normal failover logic, GetKWKID
2339 // logs error
2340 bSuccess = pLoadBalancer->GetKWKID(iIndex, lKMAID, pstSoap,
2341 acKWKID, &bClientAESKeyWrapSetupError) ? true : false;
2342 if (bSuccess)
2343 {
2344 bSuccess = KMS_Agent::soap_call_KMS_Agent__RetrieveKey2(
2345 pstSoap,
2346 sURL,
2347 NULL,
2348 pKeyID,
2349 stDataUnit,
2350 i_pKeyGroupID ? i_pKeyGroupID : (char *) "",
2351 acKWKID,
2352 //NOTE: this is ugly but the soap response struct's are the same for both flavors of CreateKey
2353 *(reinterpret_cast<struct KMS_Agent::KMS_Agent__RetrieveKey2Response *>(&oResponse))) == SOAP_OK;
2354 }
2355 }
2356 else if (bSuccess) // NO AES Key Wrap
2357 {
2358 bSuccess = KMS_Agent::soap_call_KMS_Agent__RetrieveKey(
2359 pstSoap,
2360 sURL,
2361 NULL,
2362 pKeyID,
2363 stDataUnit,
2364 i_pKeyGroupID ? i_pKeyGroupID : (char *) "",
2365 oResponse) == SOAP_OK;
2366 }
2367
2368 // don'f failover for Client side AES Key Wrap setup problems
2369 if (!bSuccess && !bClientAESKeyWrapSetupError)
2370 {
2371 iIndex = pLoadBalancer->FailOver(iIndex, pstSoap);
2372
2373 GetPeerNetworkAddress(sKmaAddress, pstSoap);
2374 GetSoapFault(sSoapFaultMsg, pstSoap);
2375
2376 LogError(i_pProfile,
2377 AUDIT_CLIENT_AGENT_RETRIEVE_KEY_SOAP_ERROR,
2378 NULL,
2379 sKmaAddress,
2380 sSoapFaultMsg);
2381 }
2382 if (bSuccess)
2383 {
2384 pLoadBalancer->UpdateResponseStatus(iIndex);
2385 }
2386 }
2387 while (iIndex >= 0 && (!bSuccess) && (!bClientAESKeyWrapSetupError));
2388 }
2389 else
2390 {
2391 bSuccess = false;
2392 }
2393
2394 if (bSuccess)
2395 {
2396 if (KMS_KEY_ID_SIZE != ConvertUTF8HexStringToBinary(
2397 oResponse.Key.KeyID, NULL))
2398 {
2399 GetPeerNetworkAddress(sKmaAddress, pstSoap);
2400 LogError(i_pProfile,
2401 AUDIT_CLIENT_AGENT_RETRIEVE_KEY_INVALID_KEYID_RESPONSE,
2402 NULL,
2403 sKmaAddress,
2404 NULL);
2405 bSuccess = false;
2406 }
2407 }
2408
2409 if (bSuccess)
2410 {
2411 ConvertUTF8HexStringToBinary(
2412 oResponse.Key.KeyID, o_pKey->m_acKeyID);
2413
2414 //if ( oResponse.Key.KeyState < (KMS_Agent__KeyState)KMS_KEY_STATE_ACTIVE_PROTECT_AND_PROCESS ||
2415 // oResponse.Key.KeyState > (KMS_Agent__KeyState)KMS_KEY_STATE_COMPROMISED )
2416 if ((KMS_AGENT_KEY_STATE) oResponse.Key.KeyState < KMS_KEY_STATE_ACTIVE_PROTECT_AND_PROCESS ||
2417 (KMS_AGENT_KEY_STATE) oResponse.Key.KeyState > KMS_KEY_STATE_COMPROMISED)
2418 {
2419 GetPeerNetworkAddress(sKmaAddress, pstSoap);
2420 LogError(i_pProfile,
2421 AUDIT_CLIENT_AGENT_RETRIEVE_KEY_INVALID_KEY_STATE_RESPONSE,
2422 NULL,
2423 sKmaAddress,
2424 NULL);
2425 bSuccess = false;
2426 }
2427
2428 o_pKey->m_iKeyState = (KMS_AGENT_KEY_STATE) oResponse.Key.KeyState;
2429
2430 if ((KMS_KEY_TYPE) oResponse.Key.KeyType != KMS_KEY_TYPE_AES_256)
2431 {
2432 GetPeerNetworkAddress(sKmaAddress, pstSoap);
2433 LogError(i_pProfile,
2434 AUDIT_CLIENT_AGENT_RETRIEVE_KEY_INVALID_KEY_TYPE_RESPONSE,
2435 NULL,
2436 sKmaAddress,
2437 NULL);
2438 bSuccess = false;
2439 }
2440
2441 o_pKey->m_iKeyType = (KMS_KEY_TYPE) oResponse.Key.KeyType;
2442
2443 if (strlen(oResponse.Key.KeyGroupID) > KMS_MAX_KEY_GROUP_ID_SIZE)
2444 {
2445 GetPeerNetworkAddress(sKmaAddress, pstSoap);
2446 LogError(i_pProfile,
2447 AUDIT_CLIENT_AGENT_RETRIEVE_KEY_INVALID_KEY_GROUP_ID_LENGTH_RESPONSE,
2448 NULL,
2449 sKmaAddress,
2450 NULL);
2451 bSuccess = false;
2452 }
2453 else
2454 {
2455 strncpy(o_pKey->m_acKeyGroupID,
2456 oResponse.Key.KeyGroupID,
2457 sizeof(o_pKey->m_acKeyGroupID));
2458 o_pKey->m_acKeyGroupID[sizeof(o_pKey->m_acKeyGroupID)-1] = '\0';
2459 }
2460
2461 if ( bSuccess && pLoadBalancer->AESKeyWrapSupported(iIndex))
2462 {
2463 // verify KWK ID matches what was registered
2464 if (oResponse.Key.Key.__size != KMS_MAX_WRAPPED_KEY_SIZE)
2465 {
2466 GetPeerNetworkAddress(sKmaAddress, pstSoap);
2467 LogError(i_pProfile,
2468 AUDIT_CLIENT_AGENT_RETRIEVE_KEY_INVALID_WRAPPED_KEY_LENGTH_RESPONSE,
2469 NULL,
2470 sKmaAddress,
2471 NULL);
2472 bSuccess = false;
2473 }
2474 else
2475 {
2476 if (pLoadBalancer->AESKeyUnwrap(&iIndex, oResponse.Key.Key.__ptr,
2477 o_pKey->m_acKey) == false)
2478 {
2479 GetPeerNetworkAddress(sKmaAddress, pstSoap);
2480 LogError(i_pProfile,
2481 AUDIT_CLIENT_AGENT_RETRIEVE_KEY_AESKEYUNWRAP_ERROR,
2482 NULL,
2483 sKmaAddress,
2484 NULL);
2485
2486 bSuccess = false;
2487 }
2488 }
2489 }
2490 else if (bSuccess) // non-AES key wrap
2491 {
2492 if (oResponse.Key.Key.__size != KMS_MAX_KEY_SIZE)
2493 {
2494 GetPeerNetworkAddress(sKmaAddress, pstSoap);
2495 LogError(i_pProfile,
2496 AUDIT_CLIENT_AGENT_RETRIEVE_KEY_INVALID_KEY_LENGTH_RESPONSE,
2497 NULL,
2498 sKmaAddress,
2499 NULL);
2500 bSuccess = false;
2501 }
2502 else
2503 {
2504 memcpy(o_pKey->m_acKey,
2505 oResponse.Key.Key.__ptr,
2506 KMS_MAX_KEY_SIZE);
2507 }
2508 }
2509
2510 if (bSuccess)
2511 {
2512 o_pKey->m_iKeyLength = KMS_MAX_KEY_SIZE;
2513
2514 if (KMSAgentKeyCallout(o_pKey->m_acKey) != 0)
2515 {
2516 LogError(i_pProfile,
2517 AUDIT_CLIENT_AGENT_RETRIEVE_KEY_KEY_CALLOUT_ERROR,
2518 NULL,
2519 NULL,
2520 NULL);
2521 bSuccess = false;
2522 }
2523 }
2524 }
2525
2526 // free allocated memory for output if error condition
2527 // Clean up SOAP
2528
2529 soap_destroy(pstSoap);
2530 soap_end(pstSoap);
2531
2532 if (bSuccess)
2533 {
2534 RETURN(KMS_AGENT_STATUS_OK);
2535 }
2536
2537 RETURN(KMSAgent_GetLastStatusCode(i_pProfile,
2538 bClientAESKeyWrapSetupError ?
2539 CAgentLoadBalancer::AES_KEY_WRAP_SETUP_ERROR : iIndex));
2540 }
2541
2542 extern "C"
KMSAgent_RetrieveDataUnit(KMSClientProfile * const i_pProfile,const unsigned char * const i_pDataUnitID,const unsigned char * const i_pExternalUniqueID,int i_iExternalUniqueIDLen,utf8cstr const i_pExternalTag,utf8cstr const i_pDescription,KMSAgent_DataUnit * const o_pDataUnit)2543 KMS_AGENT_STATUS KMSAgent_RetrieveDataUnit (
2544 KMSClientProfile * const i_pProfile,
2545 const unsigned char * const i_pDataUnitID,
2546 const unsigned char * const i_pExternalUniqueID,
2547 int i_iExternalUniqueIDLen,
2548 utf8cstr const i_pExternalTag,
2549 utf8cstr const i_pDescription,
2550 KMSAgent_DataUnit * const o_pDataUnit)
2551 {
2552 bool bSuccess;
2553 #if defined(METAWARE)
2554 ECPT_TRACE_ENTRY *trace = NULL;
2555 ECPT_TRACE(trace, KMSAgent_RetrieveDataUnit);
2556 #endif
2557
2558 #if defined(DEBUG) && defined(METAWARE)
2559 log_printf("KMSAgent_RetrieveDataUnit entered\n");
2560 #endif
2561
2562 // required parms
2563 if (!i_pProfile)
2564 {
2565 Log(AUDIT_CLIENT_AGENT_RETRIEVE_DATA_UNIT_INVALID_PARAMETERS,
2566 NULL,
2567 NULL,
2568 "Profile arg");
2569 RETURN(KMS_AGENT_STATUS_INVALID_PARAMETER);
2570 }
2571 if (!i_pDataUnitID)
2572 {
2573 Log(AUDIT_CLIENT_AGENT_RETRIEVE_DATA_UNIT_INVALID_PARAMETERS,
2574 NULL,
2575 NULL,
2576 "DataUnitID arg");
2577 RETURN(KMS_AGENT_STATUS_INVALID_PARAMETER);
2578 }
2579 if (!o_pDataUnit)
2580 {
2581 Log(AUDIT_CLIENT_AGENT_RETRIEVE_DATA_UNIT_INVALID_PARAMETERS,
2582 NULL,
2583 NULL,
2584 "DataUnit arg");
2585 RETURN(KMS_AGENT_STATUS_INVALID_PARAMETER);
2586 }
2587
2588
2589
2590 if (!KMSClient_ProfileLoaded(i_pProfile))
2591 {
2592 #if defined(DEBUG) && defined(METAWARE)
2593 log_printf("KMSAgent_RetrieveDataUnit profile not loaded\n");
2594 #endif
2595 RETURN(KMS_AGENT_STATUS_PROFILE_NOT_LOADED);
2596 }
2597
2598 CAutoMutex oAutoMutex((K_MUTEX_HANDLE) i_pProfile->m_pLock);
2599
2600 // validate input parms
2601
2602 if (i_pExternalUniqueID &&
2603 (i_iExternalUniqueIDLen <= 0 ||
2604 i_iExternalUniqueIDLen > KMS_MAX_EXTERNAL_UNIQUE_ID_SIZE))
2605 {
2606 Log(AUDIT_CLIENT_AGENT_RETRIEVE_DATA_UNIT_INVALID_PARAMETERS,
2607 NULL,
2608 NULL,
2609 "ExternalUniqueID arg");
2610 RETURN(KMS_AGENT_STATUS_INVALID_PARAMETER);
2611 }
2612
2613 if (i_pExternalTag && strlen(i_pExternalTag) > KMS_MAX_EXTERNAL_TAG)
2614 {
2615 Log(AUDIT_CLIENT_AGENT_RETRIEVE_DATA_UNIT_INVALID_PARAMETERS,
2616 NULL,
2617 NULL,
2618 "ExternalTag arg");
2619 RETURN(KMS_AGENT_STATUS_INVALID_PARAMETER);
2620 }
2621
2622 if (i_pDescription &&
2623 strlen(i_pDescription) > KMS_MAX_DESCRIPTION)
2624 {
2625 Log(AUDIT_CLIENT_AGENT_RETRIEVE_DATA_UNIT_INVALID_PARAMETERS,
2626 NULL,
2627 NULL,
2628 "Description arg");
2629 RETURN(KMS_AGENT_STATUS_INVALID_PARAMETER);
2630 }
2631
2632 // prepare args to soap transaction
2633
2634 struct soap *pstSoap = (struct soap *) i_pProfile->m_pvSoap;
2635 struct KMS_Agent::KMS_Agent__RetrieveDataUnitResponse oResponse;
2636
2637 char * pDataUnitID = NULL;
2638 pDataUnitID = ConvertBinaryDataFromRequest(pstSoap,
2639 i_pDataUnitID,
2640 KMS_DATA_UNIT_ID_SIZE);
2641 //sizeof(DATA_UNIT_ID) );
2642 if (pDataUnitID == NULL)
2643 {
2644 soap_destroy(pstSoap);
2645 soap_end(pstSoap);
2646 // no memory dont' log
2647 RETURN(KMS_AGENT_STATUS_NO_MEMORY);
2648 }
2649
2650 char * pExternalUniqueID = NULL;
2651 if (i_pExternalUniqueID)
2652 {
2653 pExternalUniqueID = ConvertBinaryDataFromRequest(pstSoap,
2654 i_pExternalUniqueID,
2655 i_iExternalUniqueIDLen);
2656 if (pExternalUniqueID == NULL)
2657 {
2658 soap_destroy(pstSoap);
2659 soap_end(pstSoap);
2660 // no memory dont' log
2661 RETURN(KMS_AGENT_STATUS_NO_MEMORY);
2662 }
2663 }
2664
2665 char * pExternalTag = NULL;
2666 if (i_pExternalTag)
2667 {
2668 pExternalTag = ConvertUTF8StringFromRequest(pstSoap,
2669 i_pExternalTag,
2670 KMS_MAX_EXTERNAL_TAG + 1);
2671 if (pExternalTag == NULL)
2672 {
2673 soap_destroy(pstSoap);
2674 soap_end(pstSoap);
2675 // no memory dont' log
2676 RETURN(KMS_AGENT_STATUS_NO_MEMORY);
2677 }
2678 }
2679
2680 char * pDescription = NULL;
2681 if (i_pDescription)
2682 {
2683 pDescription = ConvertUTF8StringFromRequest(pstSoap,
2684 i_pDescription,
2685 KMS_MAX_DESCRIPTION + 1);
2686 if (pDescription == NULL)
2687 {
2688 soap_destroy(pstSoap);
2689 soap_end(pstSoap);
2690 // no memory dont' log
2691 RETURN(KMS_AGENT_STATUS_NO_MEMORY);
2692 }
2693 }
2694
2695 CAgentLoadBalancer *pLoadBalancer =
2696 (CAgentLoadBalancer *) i_pProfile->m_pAgentLoadBalancer;
2697 int iIndex = pLoadBalancer->BalanceByDataUnitID(i_pDataUnitID,
2698 KMS_DATA_UNIT_ID_SIZE);
2699
2700 if ( iIndex >= 0 )
2701 {
2702 do
2703 {
2704 const char* sURL = pLoadBalancer->GetHTTPSURL(
2705 iIndex,
2706 i_pProfile->m_iPortForAgentService);
2707
2708 strncpy(i_pProfile->m_sURL, sURL, sizeof(i_pProfile->m_sURL));
2709
2710 i_pProfile->m_sURL[sizeof(i_pProfile->m_sURL)-1] = '\0';
2711
2712 bSuccess = KMS_Agent::soap_call_KMS_Agent__RetrieveDataUnit(
2713 pstSoap,
2714 sURL,
2715 NULL,
2716 pDataUnitID,
2717 i_pExternalUniqueID ? pExternalUniqueID : (char *) "",
2718 i_pExternalTag ? pExternalTag : (char *) "",
2719 i_pDescription ? pDescription : (char *) "",
2720 oResponse) == SOAP_OK;
2721
2722 if (!bSuccess)
2723 {
2724 iIndex = pLoadBalancer->FailOver(iIndex, pstSoap);
2725
2726 char sKmaAddress[g_iMAX_PEER_NETWORK_ADDRESS_LENGTH];
2727 char sSoapFaultMsg[g_iMAX_SOAP_FAULT_MESSAGE_LENGTH];
2728
2729 GetPeerNetworkAddress(sKmaAddress, pstSoap);
2730 GetSoapFault(sSoapFaultMsg, pstSoap);
2731
2732 LogError(i_pProfile,
2733 AUDIT_CLIENT_AGENT_RETRIEVE_DATA_UNIT_SOAP_ERROR,
2734 NULL,
2735 sKmaAddress,
2736 sSoapFaultMsg);
2737 }
2738 else
2739 {
2740 pLoadBalancer->UpdateResponseStatus(iIndex);
2741 }
2742 }
2743 while (iIndex >= 0 && (!bSuccess));
2744 }
2745 else
2746 {
2747 bSuccess = false;
2748 }
2749
2750 if (bSuccess)
2751 {
2752 ConvertUTF8HexStringToBinary(
2753 oResponse.DataUnit.DataUnitID, o_pDataUnit->m_acDataUnitID);
2754
2755 o_pDataUnit->m_iExternalUniqueIDLength = ConvertUTF8HexStringToBinary(
2756 oResponse.DataUnit.ExternalUniqueID, o_pDataUnit->m_acExternalUniqueID);
2757
2758 if (strlen(oResponse.DataUnit.ExternalTag) > KMS_MAX_EXTERNAL_TAG)
2759 {
2760 LogError(i_pProfile,
2761 AUDIT_CLIENT_AGENT_RETRIEVE_DATA_UNIT_RESPONSE_INVALID_EXTERNAL_TAG_LENGTH,
2762 NULL,
2763 NULL,
2764 NULL);
2765 bSuccess = false;
2766 }
2767 else
2768 {
2769 strncpy(o_pDataUnit->m_acExternalTag,
2770 oResponse.DataUnit.ExternalTag,
2771 sizeof(o_pDataUnit->m_acExternalTag));
2772 o_pDataUnit->m_acExternalTag[sizeof(o_pDataUnit->m_acExternalTag)-1] = '\0';
2773 }
2774
2775 if (strlen(oResponse.DataUnit.Description) > KMS_MAX_DESCRIPTION)
2776 {
2777 LogError(i_pProfile,
2778 AUDIT_CLIENT_AGENT_RETRIEVE_DATA_UNIT_RESPONSE_INVALID_DESCRIPTION_LENGTH,
2779 NULL,
2780 NULL,
2781 NULL);
2782 bSuccess = false;
2783 }
2784 else
2785 {
2786 strcpy(o_pDataUnit->m_acDescription,
2787 oResponse.DataUnit.Description);
2788 }
2789
2790 o_pDataUnit->m_iDataUnitState =
2791 (KMS_AGENT_DATA_UNIT_STATE) oResponse.DataUnit.DataUnitState;
2792 }
2793
2794 // free allocated memory for output if error condition
2795 // Clean up SOAP
2796
2797 soap_destroy(pstSoap);
2798 soap_end(pstSoap);
2799
2800 if (bSuccess)
2801 {
2802 RETURN(KMS_AGENT_STATUS_OK);
2803 }
2804
2805 RETURN(KMSAgent_GetLastStatusCode(i_pProfile, iIndex));
2806 }
2807
2808 extern "C"
KMSAgent_RetrieveDataUnitByExternalUniqueID(KMSClientProfile * const i_pProfile,const unsigned char * const i_pExternalUniqueID,int i_iExternalUniqueIDLen,utf8cstr const i_pExternalTag,utf8cstr const i_pDescription,KMSAgent_DataUnit * const o_pDataUnit)2809 KMS_AGENT_STATUS KMSAgent_RetrieveDataUnitByExternalUniqueID (
2810 KMSClientProfile * const i_pProfile,
2811 const unsigned char* const i_pExternalUniqueID,
2812 int i_iExternalUniqueIDLen,
2813 utf8cstr const i_pExternalTag,
2814 utf8cstr const i_pDescription,
2815 KMSAgent_DataUnit * const o_pDataUnit)
2816 {
2817 bool bSuccess;
2818 #if defined(METAWARE)
2819 ECPT_TRACE_ENTRY *trace = NULL;
2820 ECPT_TRACE(trace, KMSAgent_RetrieveDataUnitByExternalUniqueID);
2821 #endif
2822
2823 // required parms
2824 if (!i_pProfile)
2825 {
2826 Log(AUDIT_CLIENT_AGENT_RETRIEVE_DATA_UNIT_BY_EXTERNAL_UNIQUE_ID_INVALID_PARAMETERS,
2827 NULL,
2828 NULL,
2829 "Profile arg");
2830 RETURN(KMS_AGENT_STATUS_INVALID_PARAMETER);
2831 }
2832 if (!i_pExternalUniqueID)
2833 {
2834 Log(AUDIT_CLIENT_AGENT_RETRIEVE_DATA_UNIT_BY_EXTERNAL_UNIQUE_ID_INVALID_PARAMETERS,
2835 NULL,
2836 NULL,
2837 "ExternalUniqueID arg");
2838 RETURN(KMS_AGENT_STATUS_INVALID_PARAMETER);
2839 }
2840 if (!o_pDataUnit)
2841 {
2842 Log(AUDIT_CLIENT_AGENT_RETRIEVE_DATA_UNIT_BY_EXTERNAL_UNIQUE_ID_INVALID_PARAMETERS,
2843 NULL,
2844 NULL,
2845 "DataUnit arg");
2846 RETURN(KMS_AGENT_STATUS_INVALID_PARAMETER);
2847 }
2848
2849 if (!KMSClient_ProfileLoaded(i_pProfile))
2850 {
2851 RETURN(KMS_AGENT_STATUS_PROFILE_NOT_LOADED);
2852 }
2853
2854 CAutoMutex oAutoMutex((K_MUTEX_HANDLE) i_pProfile->m_pLock);
2855
2856 // validate input parms
2857
2858 if (i_iExternalUniqueIDLen <= 0 ||
2859 i_iExternalUniqueIDLen > KMS_MAX_EXTERNAL_UNIQUE_ID_SIZE)
2860 {
2861 Log(AUDIT_CLIENT_AGENT_RETRIEVE_DATA_UNIT_BY_EXTERNAL_UNIQUE_ID_INVALID_PARAMETERS,
2862 NULL,
2863 NULL,
2864 "ExternalUniqueIDLen arg");
2865 RETURN(KMS_AGENT_STATUS_INVALID_PARAMETER);
2866 }
2867
2868 if (i_pExternalTag && strlen(i_pExternalTag) > KMS_MAX_EXTERNAL_TAG)
2869 {
2870 Log(AUDIT_CLIENT_AGENT_RETRIEVE_DATA_UNIT_BY_EXTERNAL_UNIQUE_ID_INVALID_PARAMETERS,
2871 NULL,
2872 NULL,
2873 "ExternalTag arg");
2874 RETURN(KMS_AGENT_STATUS_INVALID_PARAMETER);
2875 }
2876
2877 if (i_pDescription &&
2878 strlen(i_pDescription) > KMS_MAX_DESCRIPTION)
2879 {
2880 Log(AUDIT_CLIENT_AGENT_RETRIEVE_DATA_UNIT_BY_EXTERNAL_UNIQUE_ID_INVALID_PARAMETERS,
2881 NULL,
2882 NULL,
2883 "Description arg");
2884 RETURN(KMS_AGENT_STATUS_INVALID_PARAMETER);
2885 }
2886
2887 // prepare args to soap transaction
2888
2889 struct soap *pstSoap = (struct soap *) i_pProfile->m_pvSoap;
2890 struct KMS_Agent::KMS_Agent__RetrieveDataUnitByExternalUniqueIDResponse oResponse;
2891
2892 char * pExternalUniqueID = NULL;
2893 pExternalUniqueID = ConvertBinaryDataFromRequest(pstSoap,
2894 i_pExternalUniqueID,
2895 i_iExternalUniqueIDLen);
2896 if (pExternalUniqueID == NULL)
2897 {
2898 soap_destroy(pstSoap);
2899 soap_end(pstSoap);
2900 // no memory dont' log
2901 RETURN(KMS_AGENT_STATUS_NO_MEMORY);
2902 }
2903
2904 char * pExternalTag = NULL;
2905 if (i_pExternalTag)
2906 {
2907 pExternalTag = ConvertUTF8StringFromRequest(pstSoap,
2908 i_pExternalTag,
2909 KMS_MAX_EXTERNAL_TAG + 1);
2910 if (pExternalTag == NULL)
2911 {
2912 soap_destroy(pstSoap);
2913 soap_end(pstSoap);
2914 // no memory dont' log
2915 RETURN(KMS_AGENT_STATUS_NO_MEMORY);
2916 }
2917 }
2918
2919 char * pDescription = NULL;
2920 if (i_pDescription)
2921 {
2922 pDescription = ConvertUTF8StringFromRequest(pstSoap,
2923 i_pDescription,
2924 KMS_MAX_DESCRIPTION + 1);
2925 if (pDescription == NULL)
2926 {
2927 soap_destroy(pstSoap);
2928 soap_end(pstSoap);
2929 // no memory dont' log
2930 RETURN(KMS_AGENT_STATUS_NO_MEMORY);
2931 }
2932 }
2933
2934 CAgentLoadBalancer *pLoadBalancer =
2935 (CAgentLoadBalancer *) i_pProfile->m_pAgentLoadBalancer;
2936 int iIndex = pLoadBalancer->Balance();
2937
2938 if ( iIndex >= 0 )
2939 {
2940 do
2941 {
2942 const char* sURL = pLoadBalancer->GetHTTPSURL(
2943 iIndex,
2944 i_pProfile->m_iPortForAgentService);
2945
2946 strncpy(i_pProfile->m_sURL, sURL, sizeof(i_pProfile->m_sURL));
2947
2948 i_pProfile->m_sURL[sizeof(i_pProfile->m_sURL)-1] = '\0';
2949
2950 bSuccess = KMS_Agent::
2951 soap_call_KMS_Agent__RetrieveDataUnitByExternalUniqueID(
2952 pstSoap,
2953 sURL,
2954 NULL,
2955 pExternalUniqueID,
2956 i_pExternalTag ? pExternalTag : (char *) "",
2957 i_pDescription ? pDescription : (char *) "",
2958 oResponse) == SOAP_OK;
2959
2960 if (!bSuccess)
2961 {
2962 iIndex = pLoadBalancer->FailOver(iIndex, pstSoap);
2963
2964 char sKmaAddress[g_iMAX_PEER_NETWORK_ADDRESS_LENGTH];
2965 char sSoapFaultMsg[g_iMAX_SOAP_FAULT_MESSAGE_LENGTH];
2966
2967 GetPeerNetworkAddress(sKmaAddress, pstSoap);
2968 GetSoapFault(sSoapFaultMsg, pstSoap);
2969
2970 LogError(i_pProfile,
2971 AUDIT_CLIENT_AGENT_RETRIEVE_DATA_UNIT_BY_EXTERNAL_UNIQUE_ID_SOAP_ERROR,
2972 NULL,
2973 sKmaAddress,
2974 sSoapFaultMsg);
2975 }
2976 else
2977 {
2978 pLoadBalancer->UpdateResponseStatus(iIndex);
2979 }
2980 }
2981 while (iIndex >= 0 && (!bSuccess));
2982 }
2983 else
2984 {
2985 bSuccess = false;
2986 }
2987
2988 if (bSuccess)
2989 {
2990 ConvertUTF8HexStringToBinary(
2991 oResponse.DataUnit.DataUnitID, o_pDataUnit->m_acDataUnitID);
2992
2993 o_pDataUnit->m_iExternalUniqueIDLength = ConvertUTF8HexStringToBinary(
2994 oResponse.DataUnit.ExternalUniqueID,
2995 o_pDataUnit->m_acExternalUniqueID);
2996
2997 if (strlen(oResponse.DataUnit.ExternalTag) > KMS_MAX_EXTERNAL_TAG)
2998 {
2999 LogError(i_pProfile,
3000 AUDIT_CLIENT_AGENT_RETRIEVE_DATA_UNIT_BY_EXTERNAL_UNIQUE_ID_RESPONSE_INVALID_EXTERNAL_TAG_LENGTH,
3001 NULL,
3002 NULL,
3003 NULL);
3004 bSuccess = false;
3005 }
3006 else
3007 {
3008 strncpy(o_pDataUnit->m_acExternalTag,
3009 oResponse.DataUnit.ExternalTag,
3010 sizeof(o_pDataUnit->m_acExternalTag));
3011 o_pDataUnit->m_acExternalTag[sizeof(o_pDataUnit->m_acExternalTag)-1] = '\0';
3012 }
3013
3014 if (strlen(oResponse.DataUnit.Description) > KMS_MAX_DESCRIPTION)
3015 {
3016 LogError(i_pProfile,
3017 AUDIT_CLIENT_AGENT_RETRIEVE_DATA_UNIT_BY_EXTERNAL_UNIQUE_ID_RESPONSE_INVALID_DESCRIPTION_LENGTH,
3018 NULL,
3019 NULL,
3020 NULL);
3021 bSuccess = false;
3022 }
3023 else
3024 {
3025 strcpy(o_pDataUnit->m_acDescription,
3026 oResponse.DataUnit.Description);
3027 }
3028
3029 o_pDataUnit->m_iDataUnitState =
3030 (KMS_AGENT_DATA_UNIT_STATE) oResponse.DataUnit.DataUnitState;
3031
3032 if (bSuccess)
3033 {
3034 // RetrieveDataUnitByExternalUniqueID may create a DU so add data unit ID
3035 // and the KMA IP address to the DU cache
3036 CDataUnitCache* pDataUnitCache = (CDataUnitCache*) i_pProfile->m_pDataUnitCache;
3037
3038 if (i_pProfile->m_iClusterDiscoveryFrequency != 0) // load balancing enabled
3039 {
3040 bSuccess = pDataUnitCache->Insert(
3041 o_pDataUnit->m_acDataUnitID,
3042 KMS_DATA_UNIT_ID_SIZE,
3043 NULL, 0,
3044 pLoadBalancer->GetApplianceNetworkAddress(iIndex));
3045 }
3046 }
3047 }
3048
3049 // free allocated memory for output if error condition
3050 // Clean up SOAP
3051
3052 soap_destroy(pstSoap);
3053 soap_end(pstSoap);
3054
3055 if (bSuccess)
3056 {
3057 RETURN(KMS_AGENT_STATUS_OK);
3058 }
3059
3060 RETURN(KMSAgent_GetLastStatusCode(i_pProfile, iIndex));
3061 }
3062
3063 extern "C"
KMSAgent_RetrieveDataUnitKeys(KMSClientProfile * const i_pProfile,const KMSAgent_DataUnit * const i_pDataUnit,int i_iPageSize,int i_iPageOffset,int * const o_piKeysRemaining,const unsigned char * const i_pKeyID,KMSAgent_ArrayOfKeys ** const o_ppKeys)3064 KMS_AGENT_STATUS KMSAgent_RetrieveDataUnitKeys (
3065 KMSClientProfile * const i_pProfile,
3066 const KMSAgent_DataUnit * const i_pDataUnit,
3067 int i_iPageSize,
3068 int i_iPageOffset,
3069 int* const o_piKeysRemaining,
3070 const unsigned char * const i_pKeyID,
3071 KMSAgent_ArrayOfKeys* * const o_ppKeys)
3072 {
3073 bool bSuccess;
3074 #if defined(METAWARE)
3075 ECPT_TRACE_ENTRY *trace = NULL;
3076 ECPT_TRACE(trace, KMSAgent_RetrieveDataUnitKeys);
3077 #endif
3078
3079 if (!i_pProfile)
3080 {
3081 Log(AUDIT_CLIENT_AGENT_RETRIEVE_DATA_UNIT_KEYS_INVALID_PARAMETERS,
3082 NULL,
3083 NULL,
3084 "Profile arg");
3085 RETURN(KMS_AGENT_STATUS_INVALID_PARAMETER);
3086 }
3087 if (!i_pDataUnit)
3088 {
3089 Log(AUDIT_CLIENT_AGENT_RETRIEVE_DATA_UNIT_KEYS_INVALID_PARAMETERS,
3090 NULL,
3091 NULL,
3092 "DataUnit arg");
3093 RETURN(KMS_AGENT_STATUS_INVALID_PARAMETER);
3094 }
3095 if (!o_piKeysRemaining)
3096 {
3097 Log(AUDIT_CLIENT_AGENT_RETRIEVE_DATA_UNIT_KEYS_INVALID_PARAMETERS,
3098 NULL,
3099 NULL,
3100 "KeysRemaining arg");
3101 RETURN(KMS_AGENT_STATUS_INVALID_PARAMETER);
3102 }
3103 if (!o_ppKeys)
3104 {
3105 Log(AUDIT_CLIENT_AGENT_RETRIEVE_DATA_UNIT_KEYS_INVALID_PARAMETERS,
3106 NULL,
3107 NULL,
3108 "Keys arg");
3109 RETURN(KMS_AGENT_STATUS_INVALID_PARAMETER);
3110 }
3111 if (i_pKeyID && i_iPageOffset != 0)
3112 {
3113 Log(AUDIT_CLIENT_AGENT_RETRIEVE_DATA_UNIT_KEYS_INVALID_PARAMETERS,
3114 NULL,
3115 NULL,
3116 "KeyID and PageOffset are mutually exclusive");
3117 RETURN(KMS_AGENT_STATUS_INVALID_PARAMETER);
3118 }
3119
3120 if (!KMSClient_ProfileLoaded(i_pProfile))
3121 {
3122 RETURN(KMS_AGENT_STATUS_PROFILE_NOT_LOADED);
3123 }
3124
3125 CAutoMutex oAutoMutex((K_MUTEX_HANDLE) i_pProfile->m_pLock);
3126
3127 // validate input parms
3128
3129 if (i_iPageSize <= 0 || i_iPageSize > KMS_MAX_PAGE_SIZE)
3130 {
3131 Log(AUDIT_CLIENT_AGENT_RETRIEVE_DATA_UNIT_KEYS_INVALID_PARAMETERS,
3132 NULL,
3133 NULL,
3134 "PageSize arg");
3135 RETURN(KMS_AGENT_STATUS_INVALID_PARAMETER);
3136 }
3137
3138 if (i_iPageOffset < 0)
3139 {
3140 Log(AUDIT_CLIENT_AGENT_RETRIEVE_DATA_UNIT_KEYS_INVALID_PARAMETERS,
3141 NULL,
3142 NULL,
3143 "PageOffset arg");
3144 RETURN(KMS_AGENT_STATUS_INVALID_PARAMETER);
3145 }
3146
3147 // prepare args to soap transaction
3148
3149 struct KMS_Agent::KMS_Agent__DataUnit stDataUnit = {"", "", "", "",
3150 (KMS_Agent::KMS_Agent__DataUnitState) 0};
3151
3152 struct soap *pstSoap = (struct soap *) i_pProfile->m_pvSoap;
3153 struct KMS_Agent::KMS_Agent__RetrieveDataUnitKeysResponse oResponse;
3154
3155 if (!CopyDataUnitFromRequest(pstSoap,
3156 &stDataUnit,
3157 i_pDataUnit))
3158 {
3159 soap_destroy(pstSoap);
3160 soap_end(pstSoap);
3161 // no memory dont' log
3162 RETURN(KMS_AGENT_STATUS_NO_MEMORY);
3163 }
3164
3165 char * pKeyID = NULL;
3166 if (i_pKeyID)
3167 {
3168 pKeyID = ConvertBinaryDataFromRequest(pstSoap,
3169 i_pKeyID,
3170 KMS_KEY_ID_SIZE);
3171 if (pKeyID == NULL)
3172 {
3173 soap_destroy(pstSoap);
3174 soap_end(pstSoap);
3175 // no memory dont' log
3176 RETURN(KMS_AGENT_STATUS_NO_MEMORY);
3177 }
3178 }
3179
3180 UTF8_KEYID acKWKID;
3181 char sKmaAddress[g_iMAX_PEER_NETWORK_ADDRESS_LENGTH];
3182 char sSoapFaultMsg[g_iMAX_SOAP_FAULT_MESSAGE_LENGTH];
3183 bool bClientAESKeyWrapSetupError = false;
3184
3185 CAgentLoadBalancer *pLoadBalancer =
3186 (CAgentLoadBalancer *) i_pProfile->m_pAgentLoadBalancer;
3187
3188 int iIndex = pLoadBalancer->BalanceByDataUnitID(i_pDataUnit->m_acDataUnitID,
3189 KMS_DATA_UNIT_ID_SIZE);
3190
3191 if (iIndex >= 0)
3192 {
3193 do
3194 {
3195 bSuccess = true;
3196
3197 const char* sURL = pLoadBalancer->GetHTTPSURL(
3198 iIndex,
3199 i_pProfile->m_iPortForAgentService);
3200
3201 strncpy(i_pProfile->m_sURL, sURL, sizeof(i_pProfile->m_sURL));
3202
3203 i_pProfile->m_sURL[sizeof(i_pProfile->m_sURL)-1] = 0;
3204
3205 Long64 lKMAID = pLoadBalancer->GetKMAID(iIndex);
3206
3207 if (bSuccess && pLoadBalancer->AESKeyWrapSupported(iIndex))
3208 {
3209 // if this fails we want to utilize normal failover logic, GetKWKID
3210 // logs error
3211 bSuccess = pLoadBalancer->GetKWKID(iIndex, lKMAID, pstSoap,
3212 acKWKID, &bClientAESKeyWrapSetupError) ? true : false;
3213 if (bSuccess)
3214 {
3215 bSuccess = KMS_Agent::soap_call_KMS_Agent__RetrieveDataUnitKeys2(
3216 pstSoap,
3217 sURL,
3218 NULL,
3219 stDataUnit,
3220 i_iPageSize,
3221 i_iPageOffset,
3222 pKeyID,
3223 acKWKID,
3224 *(reinterpret_cast<struct KMS_Agent::KMS_Agent__RetrieveDataUnitKeys2Response *>(&oResponse))) == SOAP_OK;
3225 }
3226 }
3227 else if (bSuccess) // No AES Key Wrap
3228 {
3229 bSuccess = KMS_Agent::soap_call_KMS_Agent__RetrieveDataUnitKeys(
3230 pstSoap,
3231 sURL,
3232 NULL,
3233 stDataUnit,
3234 i_iPageSize,
3235 i_iPageOffset,
3236 pKeyID,
3237 oResponse) == SOAP_OK;
3238 }
3239
3240 // don'f failover for Client side AES Key Wrap setup problems
3241 if (!bSuccess && !bClientAESKeyWrapSetupError)
3242 {
3243 iIndex = pLoadBalancer->FailOver(iIndex, pstSoap);
3244
3245 GetPeerNetworkAddress(sKmaAddress, pstSoap);
3246 GetSoapFault(sSoapFaultMsg, pstSoap);
3247
3248 LogError(i_pProfile,
3249 AUDIT_CLIENT_AGENT_RETRIEVE_DATA_UNIT_KEYS_SOAP_ERROR,
3250 NULL,
3251 sKmaAddress,
3252 sSoapFaultMsg);
3253 }
3254 if (bSuccess)
3255 {
3256 pLoadBalancer->UpdateResponseStatus(iIndex);
3257 }
3258 }
3259 while (iIndex >= 0 && (!bSuccess) && (!bClientAESKeyWrapSetupError));
3260 }
3261 else
3262 {
3263 bSuccess = false;
3264 }
3265
3266 // validate response
3267
3268 if (bSuccess && oResponse.KeysRemaining < 0)
3269 {
3270 LogError(i_pProfile,
3271 AUDIT_CLIENT_AGENT_RETRIEVE_DATA_UNIT_KEYS_INVALID_KEYS_REMAINING_RESPONSE,
3272 NULL,
3273 NULL,
3274 NULL);
3275 bSuccess = false;
3276 }
3277
3278 if (bSuccess &&
3279 (oResponse.Keys.__size < 0 ||
3280 oResponse.Keys.__size > i_iPageSize))
3281 {
3282 LogError(i_pProfile,
3283 AUDIT_CLIENT_AGENT_RETRIEVE_DATA_UNIT_KEYS_INVALID_KEYS_SIZE_RESPONSE,
3284 NULL,
3285 NULL,
3286 NULL);
3287 bSuccess = false;
3288 }
3289
3290 if ( bSuccess && pLoadBalancer->AESKeyWrapSupported(iIndex))
3291 {
3292 // verify KWK ID matches what was registered
3293 }
3294
3295 if (bSuccess)
3296 {
3297 *o_ppKeys = CopyDataUnitKeysResponse(i_pProfile, &iIndex, &oResponse.Keys);
3298
3299 if (*o_ppKeys == NULL)
3300 {
3301 // CopyDataUnitKeysResponse logs errors
3302 bSuccess = false;
3303 }
3304 *o_piKeysRemaining = (int) oResponse.KeysRemaining;
3305 }
3306
3307 // free allocated memory for output if error condition
3308 // Clean up SOAP
3309
3310 soap_destroy(pstSoap);
3311 soap_end(pstSoap);
3312
3313 if (bSuccess)
3314 {
3315 RETURN(KMS_AGENT_STATUS_OK);
3316 }
3317
3318 RETURN(KMSAgent_GetLastStatusCode(i_pProfile,
3319 bClientAESKeyWrapSetupError ?
3320 CAgentLoadBalancer::AES_KEY_WRAP_SETUP_ERROR : iIndex));
3321 }
3322
3323 extern "C"
KMSAgent_RetrieveProtectAndProcessKey(KMSClientProfile * const i_pProfile,const KMSAgent_DataUnit * const i_pDataUnit,utf8cstr const i_pKeyGroupID,KMSAgent_Key * const o_pKey)3324 KMS_AGENT_STATUS KMSAgent_RetrieveProtectAndProcessKey (
3325 KMSClientProfile * const i_pProfile,
3326 const KMSAgent_DataUnit * const i_pDataUnit,
3327 utf8cstr const i_pKeyGroupID,
3328 KMSAgent_Key * const o_pKey)
3329 {
3330 bool bSuccess;
3331 #if defined(METAWARE)
3332 ECPT_TRACE_ENTRY *trace = NULL;
3333 ECPT_TRACE(trace, KMSAgent_RetrieveProtectAndProcessKey);
3334 #endif
3335
3336 if (!i_pProfile || !i_pDataUnit || !o_pKey)
3337 {
3338 RETURN(KMS_AGENT_STATUS_INVALID_PARAMETER);
3339 }
3340
3341 if (!i_pProfile)
3342 {
3343 Log(AUDIT_CLIENT_AGENT_RETRIEVE_PROTECT_AND_PROCESS_KEY_INVALID_PARAMETERS,
3344 NULL,
3345 NULL,
3346 "Profile arg");
3347 RETURN(KMS_AGENT_STATUS_INVALID_PARAMETER);
3348 }
3349 if (!i_pDataUnit)
3350 {
3351 Log(AUDIT_CLIENT_AGENT_RETRIEVE_PROTECT_AND_PROCESS_KEY_INVALID_PARAMETERS,
3352 NULL,
3353 NULL,
3354 "DataUnit arg");
3355 RETURN(KMS_AGENT_STATUS_INVALID_PARAMETER);
3356 }
3357 if (!o_pKey)
3358 {
3359 Log(AUDIT_CLIENT_AGENT_RETRIEVE_PROTECT_AND_PROCESS_KEY_INVALID_PARAMETERS,
3360 NULL,
3361 NULL,
3362 "Key arg");
3363 RETURN(KMS_AGENT_STATUS_INVALID_PARAMETER);
3364 }
3365
3366 if (i_pKeyGroupID &&
3367 strlen(i_pKeyGroupID) > KMS_MAX_KEY_GROUP_ID_SIZE)
3368 {
3369 Log(AUDIT_CLIENT_AGENT_RETRIEVE_PROTECT_AND_PROCESS_KEY_INVALID_PARAMETERS,
3370 NULL,
3371 NULL,
3372 "GroupID arg");
3373 RETURN(KMS_AGENT_STATUS_INVALID_PARAMETER);
3374 }
3375
3376 if (!KMSClient_ProfileLoaded(i_pProfile))
3377 {
3378 RETURN(KMS_AGENT_STATUS_PROFILE_NOT_LOADED);
3379 }
3380
3381 CAutoMutex oAutoMutex((K_MUTEX_HANDLE) i_pProfile->m_pLock);
3382
3383 struct KMS_Agent::KMS_Agent__DataUnit stDataUnit ={"", "", "", "",
3384 (KMS_Agent::KMS_Agent__DataUnitState) 0};
3385
3386 struct soap *pstSoap = (struct soap *) i_pProfile->m_pvSoap;
3387 struct KMS_Agent::KMS_Agent__RetrieveProtectAndProcessKeyResponse oResponse;
3388
3389 if (i_pDataUnit != NULL)
3390 {
3391 if (!CopyDataUnitFromRequest(pstSoap,
3392 &stDataUnit,
3393 i_pDataUnit))
3394 {
3395 soap_destroy(pstSoap);
3396 soap_end(pstSoap);
3397 // no memory dont' log
3398 RETURN(KMS_AGENT_STATUS_NO_MEMORY);
3399 }
3400 }
3401
3402 char * pKeyGroupID = NULL;
3403 if (i_pKeyGroupID)
3404 {
3405 pKeyGroupID = ConvertUTF8StringFromRequest(pstSoap,
3406 i_pKeyGroupID,
3407 KMS_MAX_KEY_GROUP_ID_SIZE + 1);
3408 if (pKeyGroupID == NULL)
3409 {
3410 soap_destroy(pstSoap);
3411 soap_end(pstSoap);
3412 // no memory dont' log
3413 RETURN(KMS_AGENT_STATUS_NO_MEMORY);
3414 }
3415 }
3416
3417 char sKmaAddress[g_iMAX_PEER_NETWORK_ADDRESS_LENGTH];
3418 char sSoapFaultMsg[g_iMAX_SOAP_FAULT_MESSAGE_LENGTH];
3419 bool bClientAESKeyWrapSetupError = false;
3420 UTF8_KEYID acKWKID;
3421
3422 CAgentLoadBalancer *pLoadBalancer = (CAgentLoadBalancer *) i_pProfile->m_pAgentLoadBalancer;
3423 int iIndex = pLoadBalancer->BalanceByDataUnitID(i_pDataUnit->m_acDataUnitID,
3424 KMS_DATA_UNIT_ID_SIZE);
3425
3426 if (iIndex >= 0)
3427 {
3428 do
3429 {
3430 bSuccess = true;
3431 const char* sURL = pLoadBalancer->GetHTTPSURL(
3432 iIndex,
3433 i_pProfile->m_iPortForAgentService);
3434
3435 strncpy(i_pProfile->m_sURL, sURL, sizeof(i_pProfile->m_sURL));
3436
3437 i_pProfile->m_sURL[sizeof(i_pProfile->m_sURL)-1] = '\0';
3438
3439 Long64 lKMAID = pLoadBalancer->GetKMAID(iIndex);
3440
3441 if (bSuccess && pLoadBalancer->AESKeyWrapSupported(iIndex))
3442 {
3443 // if this fails we want to utilize normal failover logic, GetKWKID
3444 // logs error
3445 bSuccess = pLoadBalancer->GetKWKID(iIndex, lKMAID, pstSoap,
3446 acKWKID, &bClientAESKeyWrapSetupError)
3447 ? true : false;
3448 if (bSuccess)
3449 {
3450 bSuccess = KMS_Agent::soap_call_KMS_Agent__RetrieveProtectAndProcessKey2(
3451 pstSoap,
3452 sURL,
3453 NULL,
3454 stDataUnit,
3455 i_pKeyGroupID ? i_pKeyGroupID : (char *) "",
3456 acKWKID,
3457 *(reinterpret_cast<struct KMS_Agent::KMS_Agent__RetrieveProtectAndProcessKey2Response *>(&oResponse))) == SOAP_OK;
3458 }
3459 }
3460 else if (bSuccess) // No AES Key Wrap
3461 {
3462 bSuccess = KMS_Agent::soap_call_KMS_Agent__RetrieveProtectAndProcessKey(
3463 pstSoap,
3464 sURL,
3465 NULL,
3466 stDataUnit,
3467 i_pKeyGroupID ? i_pKeyGroupID : (char *) "",
3468 oResponse) == SOAP_OK;
3469 }
3470
3471 // don'f failover for Client side AES Key Wrap setup problems
3472 if (!bSuccess && !bClientAESKeyWrapSetupError)
3473 {
3474 iIndex = pLoadBalancer->FailOver(iIndex, pstSoap);
3475
3476 GetPeerNetworkAddress(sKmaAddress, pstSoap);
3477 GetSoapFault(sSoapFaultMsg, pstSoap);
3478
3479 LogError(i_pProfile,
3480 AUDIT_CLIENT_AGENT_RETRIEVE_PROTECT_AND_PROCESS_KEY_SOAP_ERROR,
3481 NULL,
3482 sKmaAddress,
3483 sSoapFaultMsg);
3484 }
3485 else
3486 {
3487 pLoadBalancer->UpdateResponseStatus(iIndex);
3488 }
3489 }
3490 while (iIndex >= 0 && (!bSuccess) && (!bClientAESKeyWrapSetupError));
3491 }
3492 else
3493 {
3494 bSuccess = false;
3495 }
3496
3497 if (bSuccess)
3498 {
3499 if (KMS_KEY_ID_SIZE != ConvertUTF8HexStringToBinary(
3500 oResponse.Key.KeyID, NULL))
3501 {
3502 GetPeerNetworkAddress(sKmaAddress, pstSoap);
3503 LogError(i_pProfile,
3504 AUDIT_CLIENT_AGENT_RETRIEVE_PROTECT_AND_PROCESS_KEY_INVALID_KEYID_RESPONSE,
3505 NULL,
3506 sKmaAddress,
3507 NULL);
3508 bSuccess = false;
3509 }
3510 }
3511
3512 if (bSuccess)
3513 {
3514 ConvertUTF8HexStringToBinary(
3515 oResponse.Key.KeyID, o_pKey->m_acKeyID);
3516
3517 if ((KMS_AGENT_KEY_STATE) oResponse.Key.KeyState < KMS_KEY_STATE_ACTIVE_PROTECT_AND_PROCESS ||
3518 (KMS_AGENT_KEY_STATE) oResponse.Key.KeyState > KMS_KEY_STATE_COMPROMISED)
3519 {
3520 GetPeerNetworkAddress(sKmaAddress, pstSoap);
3521 LogError(i_pProfile,
3522 AUDIT_CLIENT_AGENT_RETRIEVE_PROTECT_AND_PROCESS_KEY_INVALID_KEY_STATE_RESPONSE,
3523 NULL,
3524 sKmaAddress,
3525 NULL);
3526 bSuccess = false;
3527 }
3528
3529 o_pKey->m_iKeyState = (KMS_AGENT_KEY_STATE) oResponse.Key.KeyState;
3530
3531 if ((KMS_KEY_TYPE) oResponse.Key.KeyType != KMS_KEY_TYPE_AES_256)
3532 {
3533 GetPeerNetworkAddress(sKmaAddress, pstSoap);
3534 LogError(i_pProfile,
3535 AUDIT_CLIENT_AGENT_RETRIEVE_PROTECT_AND_PROCESS_KEY_INVALID_KEY_TYPE_RESPONSE,
3536 NULL,
3537 sKmaAddress,
3538 NULL);
3539 bSuccess = false;
3540 }
3541
3542 o_pKey->m_iKeyType = (KMS_KEY_TYPE) oResponse.Key.KeyType;
3543
3544 if (strlen(oResponse.Key.KeyGroupID) > KMS_MAX_KEY_GROUP_ID_SIZE)
3545 {
3546 GetPeerNetworkAddress(sKmaAddress, pstSoap);
3547 LogError(i_pProfile,
3548 AUDIT_CLIENT_AGENT_RETRIEVE_PROTECT_AND_PROCESS_KEY_INVALID_KEY_GROUP_ID_LENGTH_RESPONSE,
3549 NULL,
3550 sKmaAddress,
3551 NULL);
3552 bSuccess = false;
3553 }
3554 else
3555 {
3556 strncpy(o_pKey->m_acKeyGroupID,
3557 oResponse.Key.KeyGroupID,
3558 sizeof(o_pKey->m_acKeyGroupID));
3559 o_pKey->m_acKeyGroupID[sizeof(o_pKey->m_acKeyGroupID)-1] = '\0';
3560 }
3561
3562 if ( bSuccess && pLoadBalancer->AESKeyWrapSupported(iIndex))
3563 {
3564 // verify KWK ID matches what was registered
3565 if (oResponse.Key.Key.__size != KMS_MAX_WRAPPED_KEY_SIZE)
3566 {
3567 GetPeerNetworkAddress(sKmaAddress, pstSoap);
3568 LogError(i_pProfile,
3569 AUDIT_CLIENT_AGENT_RETRIEVE_PROTECT_AND_PROCESS_KEY_INVALID_WRAPPED_KEY_LENGTH_RESPONSE,
3570 NULL,
3571 sKmaAddress,
3572 NULL);
3573 bSuccess = false;
3574 }
3575 else
3576 {
3577 if (pLoadBalancer->AESKeyUnwrap(&iIndex, oResponse.Key.Key.__ptr,
3578 o_pKey->m_acKey) == false)
3579 {
3580 GetPeerNetworkAddress(sKmaAddress, pstSoap);
3581 LogError(i_pProfile,
3582 AUDIT_CLIENT_AGENT_RETRIEVE_PROTECT_AND_PROCESS_KEY_AESKEYUNWRAP_ERROR,
3583 NULL,
3584 sKmaAddress,
3585 NULL);
3586
3587 bSuccess = false;
3588 }
3589 }
3590 }
3591 else if (bSuccess) // non-AES key wrap
3592 {
3593 if (oResponse.Key.Key.__size != KMS_MAX_KEY_SIZE)
3594 {
3595 GetPeerNetworkAddress(sKmaAddress, pstSoap);
3596 LogError(i_pProfile,
3597 AUDIT_CLIENT_AGENT_RETRIEVE_PROTECT_AND_PROCESS_KEY_INVALID_KEY_LENGTH_RESPONSE,
3598 NULL,
3599 sKmaAddress,
3600 NULL);
3601 bSuccess = false;
3602 }
3603 else
3604 {
3605 memcpy(o_pKey->m_acKey,
3606 oResponse.Key.Key.__ptr,
3607 KMS_MAX_KEY_SIZE);
3608 }
3609 }
3610
3611 if (bSuccess)
3612 {
3613 o_pKey->m_iKeyLength = KMS_MAX_KEY_SIZE;
3614
3615 if (KMSAgentKeyCallout(o_pKey->m_acKey) != 0)
3616 {
3617 LogError(i_pProfile,
3618 AUDIT_CLIENT_AGENT_RETRIEVE_PROTECT_AND_PROCESS_KEY_KEY_CALLOUT_ERROR,
3619 NULL,
3620 NULL,
3621 NULL);
3622 bSuccess = false;
3623 }
3624 }
3625 }
3626
3627 if (bSuccess)
3628 {
3629 // add Key ID and the creating KMA IP address to the DU cache
3630 CDataUnitCache* pDataUnitCache = (CDataUnitCache*) i_pProfile->m_pDataUnitCache;
3631
3632 if (i_pProfile->m_iClusterDiscoveryFrequency != 0) // load balancing enabled
3633 {
3634 bSuccess = pDataUnitCache->Insert(
3635 NULL,
3636 0,
3637 o_pKey->m_acKeyID,
3638 KMS_KEY_ID_SIZE,
3639 pLoadBalancer->GetApplianceNetworkAddress(iIndex));
3640 }
3641 }
3642
3643 // free allocated memory for output if error condition
3644 // Clean up SOAP
3645
3646 soap_destroy(pstSoap);
3647 soap_end(pstSoap);
3648
3649 if (bSuccess)
3650 {
3651 RETURN(KMS_AGENT_STATUS_OK);
3652 }
3653
3654 RETURN(KMSAgent_GetLastStatusCode(i_pProfile,
3655 bClientAESKeyWrapSetupError ?
3656 CAgentLoadBalancer::AES_KEY_WRAP_SETUP_ERROR : iIndex));
3657 }
3658
3659 extern "C"
KMSAgent_FreeArrayOfKeys(KMSAgent_ArrayOfKeys * i_pArrayOfKeys)3660 void KMSAgent_FreeArrayOfKeys (
3661 KMSAgent_ArrayOfKeys* i_pArrayOfKeys)
3662 {
3663 #if defined(METAWARE)
3664 ECPT_TRACE_ENTRY *trace = NULL;
3665 ECPT_TRACE(trace, KMSAgent_FreeArrayOfKeys);
3666 #endif
3667 if (!i_pArrayOfKeys)
3668 {
3669 return;
3670 }
3671
3672 // free memory for all information groups
3673 if (i_pArrayOfKeys->m_pKeys)
3674 {
3675 free(i_pArrayOfKeys->m_pKeys);
3676 }
3677
3678 free(i_pArrayOfKeys);
3679 }
3680
3681 /*---------------------------------------------------------------------------
3682 * Function: KMSAgent_CreateAuditLog
3683 *
3684 *--------------------------------------------------------------------------*/
3685 extern "C"
KMSAgent_CreateAuditLog(KMSClientProfile * i_pProfile,enum KMS_AUDIT_LOG_RETENTION i_iRetention,enum KMS_AUDIT_LOG_CONDITION i_iCondition,int i_bIssueAlert,utf8cstr i_pMessage)3686 KMS_AGENT_STATUS KMSAgent_CreateAuditLog (
3687 KMSClientProfile* i_pProfile,
3688 enum KMS_AUDIT_LOG_RETENTION i_iRetention,
3689 enum KMS_AUDIT_LOG_CONDITION i_iCondition,
3690 int i_bIssueAlert,
3691 utf8cstr i_pMessage)
3692 {
3693 bool bSuccess = true;
3694 #ifdef DEBUG_TIMING
3695 ECPT_TRACE_ENTRY *trace = NULL;
3696 ECPT_TRACE(trace, KMSAgent_CreateAuditLog);
3697 #endif
3698
3699 // START_STACK_CHECK;
3700
3701 if (!i_pProfile)
3702 {
3703 Log(AUDIT_CLIENT_AGENT_CREATED_AUDIT_LOG_INVALID_PARAMETERS,
3704 NULL,
3705 NULL,
3706 "Profile arg");
3707
3708 // END_STACK_CHECK;
3709
3710 RETURN(KMS_AGENT_STATUS_INVALID_PARAMETER);
3711 }
3712
3713 // check arguments
3714 if (i_iRetention > KMS_AUDIT_LOG_SHORT_TERM_RETENTION)
3715 {
3716 Log(AUDIT_CLIENT_AGENT_CREATE_AUDIT_LOG_INVALID_PARAMETERS,
3717 NULL,
3718 NULL,
3719 "Retention arg");
3720 RETURN(KMS_AGENT_STATUS_INVALID_PARAMETER);
3721 }
3722
3723 if (i_iCondition > KMS_AUDIT_LOG_WARNING_CONDITION)
3724 {
3725 Log(AUDIT_CLIENT_AGENT_CREATE_AUDIT_LOG_INVALID_PARAMETERS,
3726 NULL,
3727 NULL,
3728 "Condition arg");
3729 RETURN(KMS_AGENT_STATUS_INVALID_PARAMETER);
3730 }
3731
3732 if (!i_pMessage || (strlen(i_pMessage) <= 0))
3733 {
3734 Log(AUDIT_CLIENT_AGENT_CREATE_AUDIT_LOG_INVALID_PARAMETERS,
3735 NULL,
3736 NULL,
3737 "Message arg");
3738 // END_STACK_CHECK;
3739 RETURN(KMS_AGENT_STATUS_INVALID_PARAMETER);
3740 }
3741 if (!KMSClient_ProfileLoaded(i_pProfile))
3742 {
3743 // END_STACK_CHECK;
3744 RETURN(KMS_AGENT_STATUS_PROFILE_NOT_LOADED);
3745 }
3746
3747 CAutoMutex oAutoMutex((K_MUTEX_HANDLE) i_pProfile->m_pLock);
3748
3749 struct soap* pstSoap = (struct soap*) i_pProfile->m_pvSoap;
3750
3751 // Create Audit Log
3752
3753 KMS_Agent::KMS_Agent__CreateAuditLogResponse oResponse;
3754
3755 CAgentLoadBalancer *pLoadBalancer =
3756 (CAgentLoadBalancer *) i_pProfile->m_pAgentLoadBalancer;
3757
3758 int iIndex = pLoadBalancer->Balance();
3759 if (iIndex >= 0)
3760 {
3761 do
3762 {
3763 const char* sURL = pLoadBalancer->
3764 GetHTTPSURL(iIndex, i_pProfile->m_iPortForAgentService);
3765 strncpy(i_pProfile->m_sURL, sURL, sizeof(i_pProfile->m_sURL));
3766 i_pProfile->m_sURL[sizeof(i_pProfile->m_sURL)-1] = '\0';
3767
3768 bSuccess = KMS_Agent::soap_call_KMS_Agent__CreateAuditLog(
3769 pstSoap,
3770 sURL,
3771 NULL,
3772 (enum KMS_Agent::KMS_Agent__AuditLogRetention)i_iRetention,
3773 (enum KMS_Agent::KMS_Agent__AuditLogCondition)i_iCondition,
3774 i_bIssueAlert ? true : false,
3775 i_pMessage,
3776 oResponse) == SOAP_OK;
3777
3778
3779 if (!bSuccess)
3780 {
3781 char sSoapFaultMsg[g_iMAX_SOAP_FAULT_MESSAGE_LENGTH];
3782 char sKmaAddress[g_iMAX_PEER_NETWORK_ADDRESS_LENGTH];
3783
3784 GetSoapFault(sSoapFaultMsg, pstSoap);
3785 GetPeerNetworkAddress(sKmaAddress, pstSoap);
3786
3787 iIndex = pLoadBalancer->FailOver(iIndex, pstSoap);
3788
3789 LogError(i_pProfile, AUDIT_CLIENT_AGENT_CREATE_AUDIT_LOG_SOAP_ERROR,
3790 NULL,
3791 sKmaAddress,
3792 sSoapFaultMsg);
3793 }
3794 else
3795 {
3796 pLoadBalancer->UpdateResponseStatus(iIndex);
3797 }
3798 }
3799 while (iIndex >= 0 && (!bSuccess));
3800 }
3801 else
3802 {
3803 bSuccess = false;
3804 }
3805
3806 // free allocated memory for output if error condition
3807 // Clean up SOAP
3808
3809 soap_destroy(pstSoap);
3810 soap_end(pstSoap);
3811
3812 if (bSuccess)
3813 {
3814 // END_STACK_CHECK;
3815 RETURN(KMS_AGENT_STATUS_OK);
3816 }
3817
3818 // END_STACK_CHECK;
3819 RETURN(KMSAgent_GetLastStatusCode(i_pProfile, iIndex));
3820 }
3821
3822 #ifdef KMSUSERPKCS12
3823 /*
3824 * This function allows the user to change the PIN on the PKCS12
3825 * file that holds the clients private key and cert.
3826 */
3827 extern "C"
KMSAgent_ChangeLocalPWD(KMSClientProfile * i_pProfile,utf8cstr const i_pOldPassphrase,utf8cstr const i_pNewPassphrase)3828 KMS_AGENT_STATUS KMSAgent_ChangeLocalPWD(
3829 KMSClientProfile* i_pProfile,
3830 utf8cstr const i_pOldPassphrase,
3831 utf8cstr const i_pNewPassphrase)
3832 {
3833 CCertificate *pCert;
3834 CPrivateKey *pKey;
3835 bool bSuccess;
3836
3837 pCert = new CCertificate;
3838 pKey = new CPrivateKey;
3839
3840 bSuccess = GetPKCS12CertAndKey(i_pProfile, i_pOldPassphrase,
3841 pCert, pKey);
3842 if (!bSuccess)
3843 return(KMSAgent_GetLastStatusCode(i_pProfile, 0));
3844
3845 bSuccess = StoreAgentPKI(i_pProfile, pCert, pKey, i_pNewPassphrase);
3846 if (!bSuccess)
3847 return(KMSAgent_GetLastStatusCode(i_pProfile, 0));
3848
3849 return (KMS_AGENT_STATUS_OK);
3850 }
3851 #endif /* KMSUSERPKCS12 */
3852