xref: /onnv-gate/usr/src/lib/libkmsagent/common/KMSAgent.h (revision 12720:3db6e0082404)
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) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
24  */
25 
26 /** @file             KMSAgent.h
27  *  @defgroup         EncryptionAgent Encryption Agent API
28  *
29  * The Agent API is used to communicate with the KMS Appliance for the
30  * purpose of registering storage devices, obtaining device keys, and
31  * receiving notifications of storage device events such as destruction.
32  *
33  */
34 #ifndef KMS_AGENT_H
35 #define KMS_AGENT_H
36 
37 #include "KMSClientProfile.h"
38 
39 /*---------------------------------------------------------------------------
40  * The following ifdef block is the standard way of creating macros which
41  * make exporting from a DLL simpler. All files within this DLL are compiled
42  * with the KMS_AGENT_EXPORT symbol defined on the command line. this symbol
43  * should not be defined on any project that uses this DLL. This way any
44  * other project whose source files include this file see KMS Agent API functions
45  * as being imported from a DLL, wheras this DLL sees symbols defined with
46  * this macro as being exported.
47  *--------------------------------------------------------------------------*/
48 #ifdef KMS_AGENT_EXPORT
49 #define KMS_AGENT_API __declspec(dllexport)
50 #else
51 #define KMS_AGENT_API __declspec(dllimport)
52 #endif
53 
54 #ifdef __cplusplus
55 extern "C" {
56 #endif
57 
58 /*---------------------------------------------------------------------------
59  * Return Codes
60  *--------------------------------------------------------------------------*/
61 
62 /**
63  * The status type returned on API calls
64  */
65 typedef int KMS_AGENT_STATUS;
66 
67 /**
68  *  successful status
69  */
70 #define KMS_AGENT_STATUS_OK                                                 0
71 
72 /* error status values */
73 /**
74  *   generic error is a catch all for a wide variety of errors, see the specific
75  *   entry in the audit log for the details.  In general, the client API will return
76  *   one of the specific status codes.
77  */
78 #define KMS_AGENT_STATUS_GENERIC_ERROR                                      100
79 
80 /**
81  * insufficient memory for the agent library to complete the request
82  */
83 #define KMS_AGENT_STATUS_NO_MEMORY                                          102
84 
85 /**
86  * parameter error, invalid input
87  */
88 #define KMS_AGENT_STATUS_INVALID_PARAMETER                                  103
89 
90 /**
91  *  an API call was made before the profile was loaded
92  */
93 #define KMS_AGENT_STATUS_PROFILE_NOT_LOADED                                 104
94 
95 /**
96  *  upon receipt of a key the callout function returned an error
97  */
98 #define KMS_AGENT_STATUS_KEY_CALLOUT_FAILURE                                105
99 
100 /**
101  *  the specified profile failover attempts have been exceeded or no KMAs are available within the cluster
102  */
103 #define KMS_AGENT_STATUS_KMS_UNAVAILABLE                                    106
104 
105 /**
106  *  the KMS does not have any keys in the READY state, this is a KMS issue that requires attention
107  *  from a KMS administrator.
108  */
109 #define KMS_AGENT_STATUS_KMS_NO_READY_KEYS                                  107
110 
111 /**
112  *   the FIPS 140-2 known answer test (KAK) failed for AES Key wrap.
113  */
114 #define KMS_AGENT_STATUS_FIPS_KAT_AES_KEYWRAP_ERROR                         108
115 
116 /**
117  *   #FIPS_MODE was specified on #KMSAgent_LoadProfile
118  *   but no FIPS compatible KMAs are currently
119  *   available.  Also, it may be that no FIPS compatible KMAs have been
120  *   configured within the KMS.
121  */
122 #define KMS_AGENT_STATUS_NO_FIPS_KMAS_AVAILABLE                             109
123 
124 /**
125  *  the profile was already successfully loaded and should be unloaded
126  *  before attempting to load it again
127  */
128 #define KMS_AGENT_STATUS_PROFILE_ALREADY_LOADED                             110
129 
130 /**
131  *   the FIPS 140-2 known answer test (KAK) failed for AES ECB.
132  */
133 #define KMS_AGENT_STATUS_FIPS_KAT_AES_ECB_ERROR                             111
134 
135 /**
136  *   the FIPS 140-2 known answer test (KAK) failed for HMAC-SHA1.
137  */
138 #define KMS_AGENT_STATUS_FIPS_KAT_HMAC_SHA1_ERROR                             112
139 
140 /*
141  *  SOAP Sender Errors - client errors associated with a KMS SOAP service
142  */
143 
144 /**
145  * the following conditions can result in access denied being returned by the KMSAgent Soap service:
146  * <ul>
147  * <li>Agent is not enabled on the KMS
148  * <li>Invalid DataUnitID or DataUnit does not exist
149  * <li>Invalid ExternalUniqueID or DataUnit does not exist with specified ID
150  * <li>Invalid ExternalTag
151  * <li>Invalid KeyID
152  * <li>Invalid KeyGroup or KeyGroup does not exist
153  * <li>The Agent ID is not recognized as an agent by the KMS, i.e. the agent may not exist or the
154  * ID represents another kind of entity.
155  * <li>No KeyGroup specified and the Agent is not configured to have a default KeyGroup
156  * <li>Agent does not have access to the specified KeyGroup
157  * </ul>
158  * to prevent leakage of information the specific details for access being denied are not
159  * disclosed.  Audit log entries at the KMS can be used to determine specific reasons for
160  * access being denied.
161  */
162 #define KMS_AGENT_STATUS_ACCESS_DENIED                                      200
163 
164 /**
165  *  This error status is only returned when received from the KMS and the transaction
166  *  timeout has been exceeded.
167  */
168 #define KMS_AGENT_STATUS_SERVER_BUSY                                        201
169 
170 /**
171  *   a data unit already exists with the specified external unique identifier
172  */
173 #define KMS_AGENT_STATUS_EXTERNAL_UNIQUE_ID_EXISTS                          202
174 
175 /**
176  *  The external unique ID specified was found to exist but the corresponding
177  *  DataUnitID did not exist.
178  */
179 #define KMS_AGENT_STATUS_DATA_UNIT_ID_NOT_FOUND_EXTERNAL_ID_EXISTS          203
180 
181 
182 /**
183  * The specified key has been destroyed or is unknown to the KMS
184  */
185 #define KMS_AGENT_STATUS_KEY_DOES_NOT_EXIST                                 204
186 
187 /**
188  * The requested key has been destroyed.
189  */
190 #define KMS_AGENT_STATUS_KEY_DESTROYED                                      205
191 
192 /**
193  *  The key received from a KMA encountered an error during AES Key Unwrapping
194  */
195 #define KMS_AGENT_AES_KEY_UNWRAP_ERROR                                      206
196 
197 /**
198  *  An error occurred during establishment of an AES Key-Encryption Key
199  */
200 #define KMS_AGENT_AES_KEY_WRAP_SETUP_ERROR                                  207
201 
202 /*
203  * Failed to decrypt the client private key data file due to incorrect PIN
204  */
205 #define	KMS_AGENT_LOCAL_AUTH_FAILURE					    208
206 
207 /**
208  *   supported key types
209  */
210 enum KMS_KEY_TYPE
211 {
212     /**
213      *  AES 256 key type
214      */
215     KMS_KEY_TYPE_AES_256
216 };
217 
218 /**
219  *  This enumerator type defines the various Key States.
220  */
221 enum KMS_AGENT_KEY_STATE
222 {
223     KMS_KEY_STATE_GENERATED = 0,
224     KMS_KEY_STATE_READY,
225 
226     /**
227      * A key in this state can be used for both encryption and decryption.
228      * A key is placed into this state when it is assigned. The assignment is done when an encryption agent requests a new key be created.
229      */
230     KMS_KEY_STATE_ACTIVE_PROTECT_AND_PROCESS,
231 
232     /**
233      * A key in this state can be used for decryption but not encryption. When an agent determines that none of the keys available to
234      * it (e.g., for a specific data unit that is being read or written) are in the protect-and-process state, it should create a new key.
235      * Keys transition from protect-and-process to process only when the encryption period for the key expires.
236      */
237     KMS_KEY_STATE_ACTIVE_PROCESS_ONLY,
238 
239     /**
240      * The key has passed its cryptoperiod but may still be needed to process (decrypt) information. Auditable events are generated
241      * when keys in this state are provided to the agent.
242      */
243     KMS_KEY_STATE_DEACTIVATED,
244 
245     /**
246      * Keys are compromised when they are released to or discovered by an unauthorized entity.
247      * Compromised keys should not be used to protect information, but may be used to process information.
248      * Auditable events are generated
249      * when keys in this state are provided to the agent.
250      */
251     KMS_KEY_STATE_COMPROMISED,
252 
253     KMS_KEY_STATE_DESTROYED_INCOMPLETE,
254     KMS_KEY_STATE_DESTROYED_COMPLETE,
255     KMS_KEY_STATE_DESTROYED_COMPROMISED_INCOMPLETE,
256     KMS_KEY_STATE_DESTROYED_COMPROMISED_COMPLETE
257 
258 };
259 
260 /*---------------------------------------------------------------------------
261  * Data Unit State
262  *--------------------------------------------------------------------------*/
263 
264 /**
265  *  this enumeration defines the DataUnit states
266  */
267 enum KMS_AGENT_DATA_UNIT_STATE
268 {
269     /**
270      * When a data unit has been created, but has not yet had any keys created it will be in "no key" state.
271      * This should be a short, transient condition that will be exited as soon as a key has been created.
272      */
273     KMS_DATA_UNIT_STATE_NO_KEY = 0,
274 
275     /**
276      * Normal is a substate of readable. In this state, a data unit has at least one protect-and-process state key that can be used to encrypt data.
277      * The data unit is therefore writable.
278      */
279     KMS_DATA_UNIT_STATE_READABLE_NORMAL,
280 
281     /**
282      * Needs rekey is a substate of readable. In this state, the data unit has no protect-and-process keys.
283      * Data should not be encrypted and written to the data unit unless the data unit is rekeyed and a new, active key is assigned.
284      * Its the responsibility of the agent to avoid using a key that is not in protect-and-process state for encryption.
285      * The data unit may have keys that are in process only, deactivated, or compromised state. Any of these keys can be used for decryption.
286      */
287     KMS_DATA_UNIT_STATE_READABLE_NEEDS_REKEY,
288 
289     /**
290      * When all of the keys for a data unit are destroyed, the data unit is shredded. The data unit cannot be read or written.
291      * However, a new key can be created for the data unit. This will return the data unit to normal state, allowing it to be read and written.
292      */
293     KMS_DATA_UNIT_STATE_SHREDDED
294 };
295 
296 /**
297  *  This enumeration type defines Audit Log Retention values
298  */
299 enum KMS_AUDIT_LOG_RETENTION
300 {
301     /**
302      * specifies that an audit log entry should have long term retention
303      */
304     KMS_AUDIT_LOG_LONG_TERM_RETENTION = 0,
305     /**
306      * specifies that an audit log entry should have medium term retention
307      */
308     KMS_AUDIT_LOG_MEDIUM_TERM_RETENTION,
309     /**
310      * specifies that an audit log entry should have short term retention
311      */
312     KMS_AUDIT_LOG_SHORT_TERM_RETENTION
313 };
314 
315 /**
316  *  This enumeration type defines Audit Log Condition values
317  */
318 enum KMS_AUDIT_LOG_CONDITION
319 {
320     /**
321      * specifies that an audit log entry should should indicate a success condition
322      */
323     KMS_AUDIT_LOG_SUCCESS_CONDITION = 0,
324 
325     /**
326      * specifies that an audit log entry should should indicate an error condition
327      */
328     KMS_AUDIT_LOG_ERROR_CONDITION,
329 
330     /**
331      * specifies that an audit log entry should should indicate a warning condition
332      */
333     KMS_AUDIT_LOG_WARNING_CONDITION
334 };
335 
336 /**
337  *   supported security modes
338  */
339 enum KMS_SECURITY_MODE
340 {
341     /**
342      *  agent will work with any level of KMA
343      */
344     DEFAULT_MODE = 0,
345 
346     /**
347      *  agent will only communicate with KMAs supporting FIPS 140-2 so that
348      *  keys are encrypted at the KMA using AES Key Wrap.
349      */
350     FIPS_MODE
351 };
352 
353 /*---------------------------------------------------------------------------
354  * API Input/Output Data Structures
355  *--------------------------------------------------------------------------*/
356 /**
357  *  typedef for descriptions used in various places within the API
358  */
359 typedef utf8char DESCRIPTION [KMS_MAX_DESCRIPTION+1];
360 
361 /**
362  *  typedef for key group ID
363  */
364 typedef utf8char KEY_GROUP_ID[KMS_MAX_ID+1];
365 
366 /**
367  *  typedef for the Key Group struct
368  */
369 typedef struct KMSAgent_KeyGroup KMSAgent_KeyGroup;
370 
371 /** \struct KMSAgent_KeyGroup
372  *  a Key Group with its ID and description
373  */
374 struct KMSAgent_KeyGroup
375 {
376     /**
377      *  the unique ID of the KeyGroup
378      */
379     KEY_GROUP_ID m_acKeyGroupID;
380 
381     /**
382      * the description of the KeyGroup
383      */
384     DESCRIPTION m_acDescription;
385 };
386 
387 /**
388  * An array of Key Groups
389  */
390 typedef struct KMSAgent_ArrayOfKeyGroups KMSAgent_ArrayOfKeyGroups;
391 
392 /** \struct KMSAgent_ArrayOfKeyGroups
393  *  An array of Key Groups
394  */
395 struct KMSAgent_ArrayOfKeyGroups
396 {
397     /**
398      *  pointer to an array of Key Groups
399      */
400     KMSAgent_KeyGroup* m_pKeyGroups;
401 
402     /**
403      *  the number of Key Groups in the array
404      */
405     int m_iSize;
406 };
407 
408 
409 /**
410  * typedef for a Key struct
411  */
412 typedef struct KMSAgent_Key KMSAgent_Key;
413 
414 /** \struct KMSAgent_Key
415  *  key and its associated properites: KeyID, state, type, lenth, KeyGroup and the Key value
416  */
417 struct KMSAgent_Key
418 {
419     /**
420      *  the unique ID of the key
421      */
422     KEY_ID m_acKeyID;
423 
424     /**
425      *  the state of the Key
426      */
427     enum KMS_AGENT_KEY_STATE m_iKeyState;
428 
429     /**
430      *  the type of the key, e.g. AES_256
431      */
432     enum KMS_KEY_TYPE m_iKeyType;
433 
434     /**
435      *  the unique ID of the KeyGroup
436      */
437     KEY_GROUP_ID m_acKeyGroupID;
438 
439     /**
440      *  the key in plaintext.
441      */
442     KEY m_acKey;
443 
444     /**
445      *  length of #m_acKey
446      */
447     int m_iKeyLength;
448 };
449 
450 /**
451  *  typedef for the External Unique ID
452  */
453 typedef unsigned char EXTERNAL_UNIQUE_ID [KMS_MAX_EXTERNAL_UNIQUE_ID_SIZE];
454 
455 /**
456  *  typedef for the Data Unit ID
457  */
458 typedef unsigned char DATA_UNIT_ID [KMS_DATA_UNIT_ID_SIZE];
459 
460 /**
461  *  typedef for the External Tag
462  */
463 typedef utf8char EXTERNAL_TAG [KMS_MAX_EXTERNAL_TAG+1];
464 
465 /**
466  * typedef for aData Unit structure.
467  */
468 typedef struct KMSAgent_DataUnit KMSAgent_DataUnit;
469 
470 /** \struct KMSAgent_DataUnit
471  *  struct for a DataUnit and its associated properties: DataUnitID, external unique ID,
472  *  external tag, description and state. Data units are associated with zero or more keys.
473  */
474 struct KMSAgent_DataUnit
475 {
476     /**
477      *  the unique DataUnit ID provided by the KMS
478      */
479     DATA_UNIT_ID m_acDataUnitID;
480 
481     /**
482      *  a unique external ID for the data unit that is provided by the agent, may be NULL if one is not provided.
483      *  The KMS will enforce the uniqueness of this identifier and not allow multiple data units having the same
484      *  #m_acExternalUniqueID value.
485      */
486     EXTERNAL_UNIQUE_ID m_acExternalUniqueID;
487     /**
488      *  the length in bytes of the #m_acExternalUniqueID field that represents the
489      *  ID. The length
490      *  must be less than or equal to #KMS_MAX_EXTERNAL_UNIQUE_ID_SIZE
491      */
492     int m_iExternalUniqueIDLength;
493 
494     /**
495      *  an external tag representing information pertinent to the data unit, for example a volume serial number
496      */
497     EXTERNAL_TAG m_acExternalTag;
498 
499     /**
500      *  a description of the data unit
501      */
502     DESCRIPTION m_acDescription;
503 
504     /**
505      *  the state of the DataUnit
506      */
507     enum KMS_AGENT_DATA_UNIT_STATE m_iDataUnitState;
508 
509 };
510 
511 /**
512  *   typedef for a list of keys
513  */
514 typedef struct KMSAgent_ArrayOfKeys KMSAgent_ArrayOfKeys;
515 
516 /** \struct KMSAgent_ArrayOfKeys
517  *  struct for an array of keys
518  */
519 struct KMSAgent_ArrayOfKeys
520 {
521     /**
522      *  keys are in chronological order based upon key creation date. However,
523      *  when page offset argument to #KMSAgent_RetrieveDataUnitKeys
524      *  is 0 the first key in the array will be the key in the
525      *  #KMS_KEY_STATE_ACTIVE_PROTECT_AND_PROCESS.
526      */
527     KMSAgent_Key* m_pKeys;
528 
529     /**
530      *  the number of keys in the list
531      */
532     int m_iSize;
533 };
534 
535 /**
536  *  @return the version string for the KMS Agent Library
537  */
538 const char * KMSAgent_GetVersion();
539 
540 /**
541  *
542  * This function initializes the KMS Agent API library. It
543  * should be called before any other functions are invoked. Internally,
544  * sets up the SSL library and Logging module.
545  *
546  * @param i_pWorkingDirectory       Working directory of the program which uses the
547  *                                  library.  Default is "." if NULL is passed.
548  * @param i_bUseFileLog:            True(1) if errors should go to a log file in the working directory.
549  *                                  If false(0) then errors will not be logged to a file.
550  *
551  * @return #KMS_AGENT_STATUS_OK
552  * @return #KMS_AGENT_STATUS_GENERIC_ERROR if library initialization fails
553  */
554 KMS_AGENT_STATUS KMSAgent_InitializeLibrary(
555                         const utf8cstr     i_pWorkingDirectory,
556                         int                i_bUseFileLog );
557 
558 /**
559  * This function exercises FIPS 140-2 Known Answer Tests for certified algorithms
560  * used in the agent toolkit.  This function should only be called once and may
561  * be called prior to #KMSAgent_InitializeLibrary.
562  *
563  * @return #KMS_AGENT_STATUS_OK
564  * @return #KMS_AGENT_STATUS_FIPS_KAT_AES_KEYWRAP_ERROR
565  * @return #KMS_AGENT_STATUS_FIPS_KAT_AES_ECB_ERROR
566  * @return #KMS_AGENT_STATUS_FIPS_KAT_HMAC_SHA1_ERROR
567  */
568 KMS_AGENT_STATUS KMSAgent_KnownAnswerTests();
569 
570 /**
571  * This function finalizes the KMS Agent API library. It should
572  * be called when the library is not needed by the program. Internally it
573  * cleans up the SSL library and Logging module.
574  *
575  * @return #KMS_AGENT_STATUS_OK
576  * @return #KMS_AGENT_STATUS_GENERIC_ERROR if library finalization fails
577  *
578  */
579 KMS_AGENT_STATUS KMSAgent_FinalizeLibrary();
580 
581 /**
582  * This function can be used to get the last error message when
583  * an API function encounters an error.  These error messages also
584  * are written to the log, if file logging was enabled during library
585  * initialization.
586  *
587  * @param     i_pProfile        an initialized #KMSClientProfile; the failed
588  *                              function must have used this profile.
589  * @return    the pointer to the last error message or NULL
590  *
591  */
592 utf8cstr KMSAgent_GetLastErrorMessage(
593                         KMSClientProfile* i_pProfile );
594 
595 
596     /**
597      * Get the cluster information by calling the KMS_Discovery service using the KMA specified in the
598      * profile, no load balancing will occur.  If discovery to this KMA fails then discovery will be
599      * attempted using previously retrieved cluster information.
600      *
601      * If #KMSAgent_LoadProfile was called with an IPv6 address for
602      * the <code>i_pInitialApplianceAddress</code> argument then the <code>o_pClusterEntryArray</code> will contain
603      * IPv6 addresses instead of IPv4 addresses for each KMA that has an IPv6 address.
604      * @see #KMSAgent_LoadProfile and #KMSAgent_SelectAppliance.
605      *
606      * If the size of the cluster returned by the KMS_Discovery servic exceeds <code>i_iClusterEntryArraySize</code>
607      * then the KMA list is filtered to contain the
608      * first <code>i_iClusterEntryArraySize</code> KMAs that meet the profile's FIPS setting, agent site and are reported as responding by the
609      * KMS discover cluster response.
610      *
611      * @param    i_pProfile               a pointer to an initialized #KMSClientProfile structure
612      * @param    i_iEntitySiteIDSize      the buffer size of the entity site ID including null terminator
613      *                                    (should be greater than #KMS_MAX_ENTITY_SITE_ID )
614      * @param    i_iClusterEntryArraySize the array size for cluster entries (must be less than or equal to #KMS_MAX_CLUSTER_NUM )
615      * @param    o_pEntitySiteID          a buffer allocated by the caller to store the agent's (aka entity) Site ID
616      * @param    o_pApplianceNum          the returned number of appliances in the cluster
617      * @param    o_pClusterEntryArray     a buffer allocated by the caller to store the array of cluster entries
618      *
619      * @return #KMS_AGENT_STATUS_OK
620      * @return #KMS_AGENT_STATUS_INVALID_PARAMETER
621      * @return #KMS_AGENT_STATUS_GENERIC_ERROR
622      * @return #KMS_AGENT_STATUS_ACCESS_DENIED
623      * @return #KMS_AGENT_STATUS_PROFILE_NOT_LOADED
624      * @return #KMS_AGENT_STATUS_SERVER_BUSY
625      * @return #KMS_AGENT_STATUS_KMS_UNAVAILABLE
626      * @return #KMS_AGENT_STATUS_NO_FIPS_KMAS_AVAILABLE
627      */
628     KMS_AGENT_STATUS KMSAgent_GetClusterInformation(
629             KMSClientProfile * const i_pProfile,
630             int i_iEntitySiteIDSize,
631             int i_iClusterEntryArraySize,
632             utf8cstr const o_pEntitySiteID,
633             int * const o_pApplianceNum,
634             KMSClusterEntry * const o_pClusterEntryArray);
635 
636 /**
637  * Specifies the Key Management Appliance to be used
638  * for retrieving cluster information.
639  *
640  * @param i_pProfile               a pointer to an initialized #KMSClientProfile
641  *                                 structure
642  * @param i_pApplianceAddress      the IP address of the appliance.  IPv6 addresses
643  *                                 must be enclosed in brackets, [], see #KMSAgent_LoadProfile.
644  *
645  * @return #KMS_AGENT_STATUS_OK
646  * @return #KMS_AGENT_STATUS_INVALID_PARAMETER
647  * @return #KMS_AGENT_STATUS_GENERIC_ERROR
648  * @return #KMS_AGENT_STATUS_PROFILE_NOT_LOADED
649  *
650  */
651 KMS_AGENT_STATUS KMSAgent_SelectAppliance(
652                         KMSClientProfile* const i_pProfile,
653                         utf8cstr const          i_pApplianceAddress );
654 
655 /**
656  * Load profile handles both agent enrollment with the KMS and post enrollment setup.
657  * <p>
658  * <b>Enrollment Behavior</b>
659  * <br>
660  * When a passphrase is supplied enrollment, or reenrollment, with a KMS cluster is attempted in order
661  * to establish a mutual trust relationship.  Enrollment occurs with the KMA in the cluster specified
662  * by <code>i_pApplianceAddress</code>.
663  * <p>
664  * The KMS CA web service is used for CA certificate retrieval prior to
665  * invoking the KMS Certificate web service. Certficate retrieval via these services
666  * uses the <code>i_pApplianceAddress</code> for enrollment. Cluster discovery is then performed to
667  * identify the set of KMAs within the cluster.
668  * Successful enrollment results in
669  * persistent storage of the CA X.509 certificate, agent X.509 certificate and private key.
670  * </p>
671  * Once enrolled successfully the KMS
672  * will then disable usage of the agent's passphrase for enrollment as a security precaution.
673  * Subsequent enrollment will require a new passphrase.
674  * <p>
675  * <b>Post Enrollment Behavior</b>
676  * <br>
677  * When a passphrase is not provided a profile is assumed to exist and the library profile structure
678  * is initialized from persistent storage with the configuration settings(agent ID,
679  * KMA service port numbers, KMA Address, transaction timeout, discovery frequency, transaction timeout
680  * and failover limit), cluster information(agent's site ID and KMA cluster information and KMA status) and
681  * enrollment items: the CA certificate, Agent Certificate and agent private key.
682  * <p>
683  * Finally, cluster discovery is performed(unless disabled), and a load balancer is initialized
684  * for balancing transactions across KMAs within the
685  * cluster and for handling transaction failover scenarios.
686  * Subsequent API calls using the profile will invoke cluster discovery at the frequency specified
687  * by <code>iClusterDiscoveryFrequency</code>.  Updated discovery information is persisted with the
688  * profile. The load balancer maintains affinity to KMAs within the same site as the agent for
689  * agent transactions unless an error requires failover
690  * to another KMA in the cluster. An agent's site ID may also be updated by a discovery
691  * operation.
692  *
693  * @param io_pProfile               a pointer to a #KMSClientProfile buffer allocated by the caller
694  * @param i_pProfileName            the profile name
695  * @param i_pAgentID                Optional.  For a new profile the encryption agent's ID is required.
696  * @param i_pPassphrase             Optional.  For a new profile the encryption agent's passphrase is required.  This passphrase
697  *                                  may only be used once for a successful retrieval of the Certificate and agent private key.
698  * @param i_pInitialApplianceAddress the initial IP Address of an Appliance in the KMS Cluster that is reachable by this agent. If
699  *                                  enrollment has previously occurred specification of an initial IP address that is not
700  *                                  a member of the profile's cluster information will force the cluster information
701  *                                  to be deleted and discovery to be performed with the new IP address.
702  *                                  An IPv6 address may be supplied but must be enclosed with brackets, [], in accordance
703  *                                  with RFC 2396, "Format for Literal IPv6 Addresses in URL's".  Supplying an IPv6 address will cause
704  *                                  the agent library to utilize KMA IPv6 addresses over IPv4 addresses when they are available,
705  *                                  otherwise IPv4 KMA addresses will be used.
706  * @param i_iTransactionTimeout     the timeout setting for a transaction in seconds, must be a positive value.
707  * @param i_iFailOverLimit          Failed KMA transactions will be retried up to this limit. Once this limit
708  *                                  has been reached API calls will return #KMS_AGENT_STATUS_KMS_UNAVAILABLE.
709  *                                  Specify -1 for unlimited failover attempts, 0 for no failover.  The worst case completion time for
710  *                                  an API call is approximately equal to <code>i_iFailOverLimit</code> * <code>i_iTransactionTimeout</code>.
711  *
712  * @param i_iClusterDiscoveryFrequency
713  *                                  frequency of calling cluster discovery service
714  *                                  in seconds (use 0 to disable load balancing and periodic cluster discovery)
715  * @param i_eKMSmode                specifies the KMS operational mode that the
716  *                                  agent should enforce.  Setting this to #FIPS_MODE
717  *                                  causes the agent to only communicate with KMAs in the
718  *                                  cluster that support AES key wrapping for key requests.
719  *                                  This is not a persisted setting and is only applicable
720  *                                  to the current session.
721  *
722  * @return #KMS_AGENT_STATUS_OK
723  * @return #KMS_AGENT_STATUS_INVALID_PARAMETER
724  * @return #KMS_AGENT_STATUS_GENERIC_ERROR
725  * @return #KMS_AGENT_STATUS_PROFILE_NOT_LOADED
726  * @return #KMS_AGENT_STATUS_PROFILE_ALREADY_LOADED
727  * @return #KMS_AGENT_STATUS_ACCESS_DENIED
728  * @return #KMS_AGENT_STATUS_SERVER_BUSY
729  * @return #KMS_AGENT_STATUS_KMS_UNAVAILABLE
730  * @return #KMS_AGENT_STATUS_NO_FIPS_KMAS_AVAILABLE
731  */
732 KMS_AGENT_STATUS KMSAgent_LoadProfile(
733                         KMSClientProfile* const io_pProfile,
734                         utf8cstr const          i_pProfileName,
735                         utf8cstr const          i_pAgentID,
736                         utf8cstr const          i_pPassphrase,
737                         utf8cstr const          i_pInitialApplianceAddress,
738                         int                     i_iTransactionTimeout,
739                         int                     i_iFailOverLimit,
740                         int                     i_iClusterDiscoveryFrequency,
741                         int                     i_eKMSmode );
742 
743 
744 /**
745  * Destroy the profile information in memory, the agent's profile configuration,
746  * cluster information, certificate and
747  * private key are retained in persistant storage.
748  *
749  * @param i_pProfile        a pointer to an initialized KMSClientProfile
750  *                          structure.
751  *
752  * @return #KMS_AGENT_STATUS_OK
753  * @return #KMS_AGENT_STATUS_INVALID_PARAMETER
754  *
755  */
756 KMS_AGENT_STATUS KMSAgent_UnloadProfile(
757                         KMSClientProfile* const i_pProfile );
758 
759 /**
760  * Delete the profile information from persistent storage.  The agent's profile configuration,
761  * cluster information, certificate and
762  * private key are discared, see #KMSAgent_LoadProfile for how to initialize
763  * the profile again.  The profile should be unloaded prior to making this call.
764  *
765  * @param i_pProfileName          the profile name
766  *
767  * @return #KMS_AGENT_STATUS_OK
768  * @return #KMS_AGENT_STATUS_INVALID_PARAMETER
769  * @return #KMS_AGENT_STATUS_GENERIC_ERROR
770  */
771 KMS_AGENT_STATUS KMSAgent_DeleteProfile(
772                         utf8cstr i_pProfileName );
773 
774 /**
775  * Fetch the key groups this agent is allowed to access.  The caller should invoke #KMSAgent_FreeArrayOfKeyGroups
776  * to release the allocated memory resources for the array. Up to #KMS_MAX_LIST_KEY_GROUPS key groups will be
777  * returned.
778  *
779  * @param i_pProfile       an initialized #KMSClientProfile
780  * @param o_ppKeyGroups    a buffer allocated by this routine for the array of Key Groups and individual key groups
781  *                         that this agent is allowed to access
782  *
783  * @return #KMS_AGENT_STATUS_OK
784  * @return #KMS_AGENT_STATUS_INVALID_PARAMETER
785  * @return #KMS_AGENT_STATUS_PROFILE_NOT_LOADED
786  * @return #KMS_AGENT_STATUS_NO_MEMORY
787  * @return #KMS_AGENT_STATUS_GENERIC_ERROR
788  * @return #KMS_AGENT_STATUS_ACCESS_DENIED
789  * @return #KMS_AGENT_STATUS_INVALID_PARAMETER
790  * @return #KMS_AGENT_STATUS_SERVER_BUSY
791  * @return #KMS_AGENT_STATUS_KMS_UNAVAILABLE
792  * @return #KMS_AGENT_STATUS_NO_FIPS_KMAS_AVAILABLE
793  */
794 KMS_AGENT_STATUS KMSAgent_ListKeyGroups(
795                          KMSClientProfile* const 	       i_pProfile,
796                          KMSAgent_ArrayOfKeyGroups** const o_ppKeyGroups );
797 
798 /**
799  * Helper function which frees memory allocated for the output
800  * to #KMSAgent_ListKeyGroups.
801  *
802  * @param i_pArrayOfKeyGroups   a pointer to #KMSAgent_ArrayOfKeyGroups
803  *
804  * @return void
805  *
806  */
807 void KMSAgent_FreeArrayOfKeyGroups(
808                          KMSAgent_ArrayOfKeyGroups* i_pArrayOfKeyGroups );
809 
810 /**
811  *  Creates a Key for the specified data unit. If a data unit is provided then the key will be associated with
812  *  the data unit.  The type of key created is dictated by the KMS key policy for the key group.  This policy is set up by KMS
813  *  administrators to be compatible with agents associated with the key group.
814  *  If KeyGroup is provided then the new key is associated with the specified KeyGroup, otherwise the agent's
815  *  default KeyGroup is associated with the key.
816  *  @param i_pProfile               an initialized #KMSClientProfile
817  *  @param i_pDataUnit              Optional. a pointer to a data unit to be associated with the key, if known.
818  *  @param i_pKeyGroupID            Optional, the KeyGroup ID to be assigned to the new Key, if known.  Pass NULL
819  *                                  if unknown and the new key will be associated with the agent's default key group
820  *  @param o_pKey                   A pointer to a buffer for returning the new key and key associated data.
821  *
822  *  @return #KMS_AGENT_STATUS_OK
823  *  @return #KMS_AGENT_STATUS_INVALID_PARAMETER
824  *  @return #KMS_AGENT_STATUS_PROFILE_NOT_LOADED
825  *  @return #KMS_AGENT_STATUS_NO_MEMORY
826  *  @return #KMS_AGENT_STATUS_KEY_CALLOUT_FAILURE
827  *  @return #KMS_AGENT_STATUS_GENERIC_ERROR
828  *  @return #KMS_AGENT_STATUS_ACCESS_DENIED
829  *  @return #KMS_AGENT_STATUS_SERVER_BUSY
830  *  @return #KMS_AGENT_STATUS_EXTERNAL_UNIQUE_ID_EXISTS
831  *  @return #KMS_AGENT_STATUS_KMS_UNAVAILABLE
832  *  @return #KMS_AGENT_STATUS_KMS_NO_READY_KEYS
833  *  @return #KMS_AGENT_STATUS_NO_FIPS_KMAS_AVAILABLE
834  *  @return #KMS_AGENT_AES_KEY_UNWRAP_ERROR
835  *  @return #KMS_AGENT_AES_KEY_WRAP_SETUP_ERROR
836  */
837 KMS_AGENT_STATUS KMSAgent_CreateKey(
838                         KMSClientProfile* const        i_pProfile,
839                         const KMSAgent_DataUnit* const i_pDataUnit,
840                         KEY_GROUP_ID const             i_pKeyGroupID,
841                         KMSAgent_Key* const            o_pKey);
842 
843 /**
844  *  Creates a DataUnit with the specified external unique id and external tag.
845  *
846  *  @param i_pProfile                   an initialized #KMSClientProfile
847  *  @param i_pExternalUniqueID          Optional. A unique data unit identifier to be associated with
848  *                                      the data unit. Uniqueness is enforced by the KMS. See also #KMSAgent_RetrieveDataUnit.
849  *  @param i_iExternalUniqueIDIDLen     Length in bytes of the external unique identifier.  If
850  *                                      <code>i_pExternalUniqueID</code> is NULL then this field is ignored, otherwise a positive length must be provided.
851  *  @param i_pExternalTag               Optional, but recommended. Pointer to an External Tag for the data unit, e.g. a volume serial number.
852  *  @param i_pDescription               Optional, a textual description of the data unit.
853  *  @param o_pDataUnit                  a pointer to a DataUnit buffer where
854  *                                      data unit information is returned
855  *
856  *  @return #KMS_AGENT_STATUS_OK
857  *  @return #KMS_AGENT_STATUS_INVALID_PARAMETER
858  *  @return #KMS_AGENT_STATUS_PROFILE_NOT_LOADED
859  *  @return #KMS_AGENT_STATUS_NO_MEMORY
860  *  @return #KMS_AGENT_STATUS_GENERIC_ERROR
861  *  @return #KMS_AGENT_STATUS_ACCESS_DENIED
862  *  @return #KMS_AGENT_STATUS_SERVER_BUSY
863  *  @return #KMS_AGENT_STATUS_EXTERNAL_UNIQUE_ID_EXISTS
864  *  @return #KMS_AGENT_STATUS_KMS_UNAVAILABLE
865  *  @return #KMS_AGENT_STATUS_NO_FIPS_KMAS_AVAILABLE
866 */
867 KMS_AGENT_STATUS KMSAgent_CreateDataUnit(
868                         KMSClientProfile* const    i_pProfile,
869                         const unsigned char *      i_pExternalUniqueID,
870                         int                        i_iExternalUniqueIDIDLen,
871                         utf8cstr const             i_pExternalTag,
872                         utf8cstr const             i_pDescription,
873                         KMSAgent_DataUnit* const   o_pDataUnit);
874 
875 /**
876  *  The agent may use this function to inform the KMS that the DataUnit has, or will be, overwritten.
877  *  The KMS will remove the association from the specified DataUnit to all its keys, excluding its key
878  *  in the #KMS_KEY_STATE_ACTIVE_PROTECT_AND_PROCESS state. By utilizing this API, agent's can help keep the
879  *  number of keys returned by #KMSAgent_RetrieveDataUnitKeys to just the keys being used on the Data Unit.
880  *
881  *  @param i_pProfile       an initialized #KMSClientProfile
882  *  @param i_pDataUnit      A pointer to the data unit
883  *
884  *  @return #KMS_AGENT_STATUS_OK
885  *  @return #KMS_AGENT_STATUS_INVALID_PARAMETER
886  *  @return #KMS_AGENT_STATUS_PROFILE_NOT_LOADED
887  *  @return #KMS_AGENT_STATUS_NO_MEMORY
888  *  @return #KMS_AGENT_STATUS_GENERIC_ERROR
889  *  @return #KMS_AGENT_STATUS_ACCESS_DENIED
890  *  @return #KMS_AGENT_STATUS_SERVER_BUSY
891  *  @return #KMS_AGENT_STATUS_EXTERNAL_UNIQUE_ID_EXISTS
892  *  @return #KMS_AGENT_STATUS_KMS_UNAVAILABLE
893  *  @return #KMS_AGENT_STATUS_NO_FIPS_KMAS_AVAILABLE
894  */
895 KMS_AGENT_STATUS KMSAgent_DisassociateDataUnitKeys(
896                     KMSClientProfile* const            i_pProfile,
897                     const KMSAgent_DataUnit* const     i_pDataUnit);
898 
899 
900 /**
901  *  retrieve a key by the Key's ID, optionally specifying the Data Unit and KeyGroup to be
902  *  associated with the key.  Supplying the Data Unit information allows the KMS to add an
903  *  association between the Key and the Data Unit. The assumption being made is that the key being
904  *  retrieved has been used on the specified Data Unit and needs to be associated with it.  This
905  *  side affect allows the KMS to build up its knowledge of key usage as it relies upon agents
906  *  for discovering and reporting how keys are being used on Data Units.  For example, when keys
907  *  are imported into a KMS the information associating keys with DataUnits may not be provided,
908  *  consequently the KMS is unaware of what DataUnits were encrypted with a particular key.
909  *
910  *  @param i_pProfile       an initialized KMSClientProfile
911  *  @param i_pKeyID         The ID of the Key being requested
912  *  @param i_pDataUnit      Optional. If non-NULL, the  KMS will verify that an association exists between the key and the Data Unit and create
913  *                          the association if it is missing.
914  *  @param i_pKeyGroupID    Optional. If non-NULL, and the key is not already associated with a KeyGroup, then the KMS will associate the key with the specified KeyGroup.
915  *  @param o_pKey           A pointer to a buffer allcoated by the caller for returning the new key and key associated data.
916  *
917  *  @return #KMS_AGENT_STATUS_OK
918  *  @return #KMS_AGENT_STATUS_INVALID_PARAMETER
919  *  @return #KMS_AGENT_STATUS_PROFILE_NOT_LOADED
920  *  @return #KMS_AGENT_STATUS_NO_MEMORY
921  *  @return #KMS_AGENT_STATUS_KEY_CALLOUT_FAILURE
922  *  @return #KMS_AGENT_STATUS_GENERIC_ERROR
923  *  @return #KMS_AGENT_STATUS_ACCESS_DENIED
924  *  @return #KMS_AGENT_STATUS_SERVER_BUSY
925  *  @return #KMS_AGENT_STATUS_EXTERNAL_UNIQUE_ID_EXISTS
926  *  @return #KMS_AGENT_STATUS_KEY_DOES_NOT_EXIST
927  *  @return #KMS_AGENT_STATUS_KEY_DESTROYED
928  *  @return #KMS_AGENT_STATUS_KMS_UNAVAILABLE
929  *  @return #KMS_AGENT_STATUS_NO_FIPS_KMAS_AVAILABLE
930  *  @return #KMS_AGENT_AES_KEY_UNWRAP_ERROR
931  *  @return #KMS_AGENT_AES_KEY_WRAP_SETUP_ERROR
932  */
933 KMS_AGENT_STATUS KMSAgent_RetrieveKey(
934                         KMSClientProfile* const              i_pProfile,
935                         const unsigned char * const          i_pKeyID,
936                         const KMSAgent_DataUnit* const       i_pDataUnit,
937                         utf8cstr const                       i_pKeyGroupID,
938                         KMSAgent_Key* const                  o_pKey);
939 
940 /**
941  *  Retrieve a Data Unit by its data unit identifier.
942  *
943  *  @param i_pProfile                   an initialized #KMSClientProfile
944  *  @param i_pDataUnitID                the data unit ID by which retrieval will be performed
945  *  @param i_pExternalUniqueID          Optional, a unique data unit identifier to be associated with
946  *                                      the data unit. Uniqueness is enforced by the KMS.
947  *  @param i_iExternalUniqueIDLen       Length in bytes of the external unique identifier, must be positive.  If
948  *                                      <code>i_pExternalUniqueID</code> is NULL then this field is ignored.
949  *  @param i_pExternalTag               Optional, but recommended. Pointer to a data unit external tag, e.g. volser
950  *  @param i_pDescription               Optional, a textual description of the data unit.
951  *  @param o_pDataUnit                  a pointer to a DataUnit buffer allocated by the caller where
952  *                                      data unit information is returned
953  *
954  *  @return #KMS_AGENT_STATUS_OK
955  *  @return #KMS_AGENT_STATUS_INVALID_PARAMETER
956  *  @return #KMS_AGENT_STATUS_PROFILE_NOT_LOADED
957  *  @return #KMS_AGENT_STATUS_NO_MEMORY
958  *  @return #KMS_AGENT_STATUS_GENERIC_ERROR
959  *  @return #KMS_AGENT_STATUS_ACCESS_DENIED
960  *  @return #KMS_AGENT_STATUS_SERVER_BUSY
961  *  @return #KMS_AGENT_STATUS_EXTERNAL_UNIQUE_ID_EXISTS
962  *  @return #KMS_AGENT_STATUS_KMS_UNAVAILABLE
963  *  @return #KMS_AGENT_STATUS_NO_FIPS_KMAS_AVAILABLE
964  */
965 KMS_AGENT_STATUS KMSAgent_RetrieveDataUnit(
966                         KMSClientProfile* const         i_pProfile,
967                         const unsigned char * const     i_pDataUnitID,
968                         const unsigned char * const     i_pExternalUniqueID,
969                         int                             i_iExternalUniqueIDLen,
970                         utf8cstr const                  i_pExternalTag,
971                         utf8cstr const                  i_pDescription,
972                         KMSAgent_DataUnit* const        o_pDataUnit);
973 
974 /**
975  *  Retrieve a Data Unit by its external unique identifier.
976  *  If the KMS does not contain a data unit with the specified unique identifier then a data unit will
977  *  be created.  The new data unit will contain the external unique identifier and the external tag, if
978  *  provided.
979  *
980  *  @param i_pProfile                   an initialized #KMSClientProfile
981  *  @param i_pExternalUniqueID          A unique data unit identifier to be associated with
982  *                                      the data unit. Uniqueness is enforced by the KMS.
983  *  @param i_iExternalUniqueIDLen       Length in bytes of the external unique identifier, must be positive.
984  *  @param i_pExternalTag               Optional, but recommended. Pointer to a data unit external tag, e.g. volser
985  *  @param i_pDescription               Optional, a textual description of the data unit.
986  *  @param o_pDataUnit                  a pointer to a DataUnit buffer allocated by the caller where
987  *                                      data unit information is returned
988  *
989  *  @return #KMS_AGENT_STATUS_OK
990  *  @return #KMS_AGENT_STATUS_INVALID_PARAMETER
991  *  @return #KMS_AGENT_STATUS_PROFILE_NOT_LOADED
992  *  @return #KMS_AGENT_STATUS_NO_MEMORY
993  *  @return #KMS_AGENT_STATUS_GENERIC_ERROR
994  *  @return #KMS_AGENT_STATUS_ACCESS_DENIED
995  *  @return #KMS_AGENT_STATUS_SERVER_BUSY
996  *  @return #KMS_AGENT_STATUS_EXTERNAL_UNIQUE_ID_EXISTS
997  *  @return #KMS_AGENT_STATUS_KMS_UNAVAILABLE
998  *  @return #KMS_AGENT_STATUS_NO_FIPS_KMAS_AVAILABLE
999  */
1000 KMS_AGENT_STATUS KMSAgent_RetrieveDataUnitByExternalUniqueID(
1001                         KMSClientProfile* const         i_pProfile,
1002                         const unsigned char* const      i_pExternalUniqueID,
1003                         int                             i_iExternalUniqueIDLen,
1004                         utf8cstr const                  i_pExternalTag,
1005                         utf8cstr const                  i_pDescription,
1006                         KMSAgent_DataUnit* const        o_pDataUnit);
1007 
1008 /**
1009  *  retrieve keys assigned to a Data Unit.
1010  *  Agents should consult the state of each key that is returned and only
1011  *  use the key in the #KMS_KEY_STATE_ACTIVE_PROTECT_AND_PROCESS state for encryption. The agent service
1012  *  attempts to return the most recently created key in the #KMS_KEY_STATE_ACTIVE_PROTECT_AND_PROCESS state
1013  *  as the first key in the list when a <code>i_pKeyID</code> is not specified.  This cannot be guaranteed as
1014  *  there may not be a key in the #KMS_KEY_STATE_ACTIVE_PROTECT_AND_PROCESS state for the specified
1015  *  data unit.  The rest of the keys returned are sorted in ascending order by the time in which
1016  *  they were created on the server.
1017  *  #KMSAgent_DisassociateDataUnitKeys may be used to manage the
1018  *  size of the key list associated with a data unit.
1019  *  The <code>i_iPageSize</code>, <code>i_iPageOffset</code> and <code>o_piKeysRemaining</code> parameters may be used for retrieving
1020  *  subsets of the list. For the <code>i_pKeyID</code> argument see the parameter's description.
1021  *  Callers should invoke#KMSAgent_FreeArrayOfKeys when finished with the buffer of keys.
1022  *
1023  *  @param i_pProfile        an initialized #KMSClientProfile
1024  *  @param i_pDataUnit       The Data Unit for which all keys will be retrieved.
1025  *  @param i_iPageSize       the number of keys to be retrieved, up to #KMS_MAX_PAGE_SIZE.
1026  *  @param i_iPageOffset     the offset from the start of the data unit's key list. Set this to zero for
1027  *                           retrieval from the start of the list or if <code>i_pKeyID</code> is non-null.
1028  *                           When set to zero the first key returned in the list
1029  *                           will be the most recently created key in the #KMS_KEY_STATE_ACTIVE_PROTECT_AND_PROCESS state.
1030  *  @param o_piKeysRemaining a pointer to an integer where the number of keys remaining in the list will be returned
1031  *  @param i_pKeyID          Optional. If non-null, the caller provides a pointer to a KeyID that is used for
1032  *                           the retrieval and the list returned begins with the specified data unit's KeyID and up to
1033  *                           <code>i_iPageSize</code> keys associated with the data unit having an activation date greater than the key
1034  *                           corresponding to <code>i_pKeyID</code>.  The first key in the list is not guaranteed
1035  *                           to be in the #KMS_KEY_STATE_ACTIVE_PROTECT_AND_PROCESS state.  If the specified <code>i_pKeyID</code>
1036  *                           is not associated with the Data Unit then the behavior is like #KMSAgent_RetrieveKey and
1037  *                           a single key is returned.
1038  *                           When non-null the <code>i_iPageOffset</code>
1039  *                           argument must be 0, these arguments are mutually exclusive.
1040  *  @param o_ppKeys          a pointer to pointer to a #KMSAgent_ArrayOfKeys struct allocated by this routine for returning the specified number of
1041  *                           Data Unit's keys and key associated data.  Up to <code>i_iPageSize</code>
1042  *                           keys will be returned. Callers should invoke #KMSAgent_FreeArrayOfKeys
1043  *                           when finished with the buffer of keys.
1044  *  @return #KMS_AGENT_STATUS_OK
1045  *  @return #KMS_AGENT_STATUS_INVALID_PARAMETER
1046  *  @return #KMS_AGENT_STATUS_PROFILE_NOT_LOADED
1047  *  @return #KMS_AGENT_STATUS_NO_MEMORY
1048  *  @return #KMS_AGENT_STATUS_GENERIC_ERROR
1049  *  @return #KMS_AGENT_STATUS_ACCESS_DENIED
1050  *  @return #KMS_AGENT_STATUS_KEY_CALLOUT_FAILURE
1051  *  @return #KMS_AGENT_STATUS_SERVER_BUSY
1052  *  @return #KMS_AGENT_STATUS_EXTERNAL_UNIQUE_ID_EXISTS
1053  *  @return #KMS_AGENT_STATUS_KMS_UNAVAILABLE
1054  *  @return #KMS_AGENT_STATUS_KEY_DOES_NOT_EXIST  if <code>i_pKeyID</code> does not exist in the KMS.
1055  *  @return #KMS_AGENT_STATUS_KEY_DESTROYED if <code>i_pKeyID</code> has been destroyed.
1056  *  @return #KMS_AGENT_STATUS_NO_FIPS_KMAS_AVAILABLE
1057  *  @return #KMS_AGENT_AES_KEY_UNWRAP_ERROR
1058  *  @return #KMS_AGENT_AES_KEY_WRAP_SETUP_ERROR
1059  */
1060 KMS_AGENT_STATUS KMSAgent_RetrieveDataUnitKeys(
1061                         KMSClientProfile* const              i_pProfile,
1062                         const KMSAgent_DataUnit* const       i_pDataUnit,
1063                         int                                  i_iPageSize,
1064                         int                                  i_iPageOffset,
1065                         int* const                           o_piKeysRemaining,
1066                         const unsigned char * const          i_pKeyID,
1067                         KMSAgent_ArrayOfKeys** const         o_ppKeys);
1068 
1069 /**
1070  *  returns a key in the #KMS_KEY_STATE_ACTIVE_PROTECT_AND_PROCESS for the specified data unit.  A new
1071  *  key will be created if the data unit does not have a key in the protect and process state or if the
1072  *  agent is not authorized to access the key in the protect and process state.
1073  *  @param i_pProfile                an initialized #KMSClientProfile
1074  *  @param i_pDataUnit               The Data Unit for which a key in the protect and process state will be returned.
1075  *  @param i_pKeyGroupID             Optional. If non-NULL and a new key is to be created, the KMS will associate the key with the specified KeyGroup
1076  *  @param o_pKey                    A pointer to a buffer for returning the protect and process key.  If the data unit
1077  *                                   is associated with multiple keys in the protect and process state then the
1078  *                                   most recently created protect and process key is returned.
1079  *
1080  *  @return #KMS_AGENT_STATUS_OK
1081  *  @return #KMS_AGENT_STATUS_INVALID_PARAMETER
1082  *  @return #KMS_AGENT_STATUS_PROFILE_NOT_LOADED
1083  *  @return #KMS_AGENT_STATUS_NO_MEMORY
1084  *  @return #KMS_AGENT_STATUS_GENERIC_ERROR
1085  *  @return #KMS_AGENT_STATUS_ACCESS_DENIED
1086  *  @return #KMS_AGENT_STATUS_KEY_CALLOUT_FAILURE
1087  *  @return #KMS_AGENT_STATUS_SERVER_BUSY
1088  *  @return #KMS_AGENT_STATUS_EXTERNAL_UNIQUE_ID_EXISTS
1089  *  @return #KMS_AGENT_STATUS_KMS_UNAVAILABLE
1090  *  @return #KMS_AGENT_STATUS_KMS_NO_READY_KEYS
1091  *  @return #KMS_AGENT_STATUS_NO_FIPS_KMAS_AVAILABLE
1092  *  @return #KMS_AGENT_AES_KEY_UNWRAP_ERROR
1093  *  @return #KMS_AGENT_AES_KEY_WRAP_SETUP_ERROR
1094  */
1095 KMS_AGENT_STATUS KMSAgent_RetrieveProtectAndProcessKey(
1096                         KMSClientProfile* const              i_pProfile,
1097                         const KMSAgent_DataUnit* const       i_pDataUnit,
1098                         utf8cstr const                       i_pKeyGroupID,
1099                         KMSAgent_Key* const                  o_pKey);
1100 
1101 /**
1102  *  Helper function which frees memory allocated for the output to #KMSAgent_RetrieveDataUnitKeys.
1103  *  @param i_pArrayOfKeys  The array of keys to be freed
1104  */
1105 void KMSAgent_FreeArrayOfKeys(
1106                         KMSAgent_ArrayOfKeys*   i_pArrayOfKeys);
1107 
1108 /**
1109  *  create an entry in the KMS audit log
1110  *
1111  *  @param i_pProfile        an initialized #KMSClientProfile
1112  *  @param i_iRetention      the retention of audit log, can be one of:
1113  *                           #KMS_AUDIT_LOG_LONG_TERM_RETENTION
1114  *                           #KMS_AUDIT_LOG_MEDIUM_TERM_RETENTION
1115  *                           #KMS_AUDIT_LOG_SHORT_TERM_RETENTION
1116  *  @param i_iCondition      the condition of audit log, can be one of:
1117  *                           #KMS_AUDIT_LOG_SUCCESS_CONDITION
1118  *                           #KMS_AUDIT_LOG_ERROR_CONDITION
1119  *                           #KMS_AUDIT_LOG_WARNING_CONDITION
1120  *  @param i_bIssueAlert     issue alert (SNMP INFORM) for this audit
1121  *  @param i_pMessage        the message text to be logged
1122  *
1123  *  @return #KMS_AGENT_STATUS_OK
1124  *  @return #KMS_AGENT_STATUS_INVALID_PARAMETER
1125  *  @return #KMS_AGENT_STATUS_PROFILE_NOT_LOADED
1126  *  @return #KMS_AGENT_STATUS_GENERIC_ERROR
1127  *  @return #KMS_AGENT_STATUS_ACCESS_DENIED
1128  *  @return #KMS_AGENT_STATUS_SERVER_BUSY
1129  *  @return #KMS_AGENT_STATUS_KMS_UNAVAILABLE
1130  *  @return #KMS_AGENT_STATUS_NO_FIPS_KMAS_AVAILABLE
1131  */
1132 KMS_AGENT_STATUS KMSAgent_CreateAuditLog(
1133                         KMSClientProfile*            i_pProfile,
1134                         enum KMS_AUDIT_LOG_RETENTION i_iRetention,
1135                         enum KMS_AUDIT_LOG_CONDITION i_iCondition,
1136                         int                          i_bIssueAlert,
1137                         utf8cstr                     i_pMessage );
1138 
1139 
1140 #ifdef KMSUSERPKCS12
1141 #include <sys/types.h>
1142 KMS_AGENT_STATUS KMSAgent_ChangeLocalPWD(
1143 	KMSClientProfile* i_pProfile,
1144 	utf8cstr const i_pOldPassphrase,
1145 	utf8cstr const i_pNewPassphrase);
1146 
1147 #define	KMSAGENT_PROFILE_FLAGS	uint32_t
1148 
1149 KMS_AGENT_STATUS
1150 KMSAgent_GetProfileStatus(
1151 	char *i_pProfileName,
1152 	KMSAGENT_PROFILE_FLAGS *flags);
1153 
1154 
1155 #define	KMSAGENT_PROFILE_EXISTS_FLAG	0x01
1156 #define	KMSAGENT_CLIENTKEY_EXISTS_FLAG	0x02
1157 #endif /* KMSUSERPKCS12 */
1158 
1159 #ifdef __cplusplus
1160 }
1161 #endif
1162 
1163 #endif
1164