/// <summary> /// Restores the given key to the Vault. /// </summary> /// <param name="keyName">Name of encryption key that should be restored.</param> /// <param name="tbri">TransitBackupRestoreItem containing the backup value.</param> /// <returns>True if success.</returns> public async Task <bool> RestoreKey(string keyName, TransitBackupRestoreItem tbri) { string path = MountPointPath + "restore/" + keyName; // Setup Post Parameters in body. Dictionary <string, string> contentParams = new Dictionary <string, string>(); try { // Build the parameter list. contentParams.Add("backup", tbri.KeyBackup); VaultDataResponseObjectB vdro = await ParentVault._httpConnector.PostAsync_B(path, "RestoreKey", contentParams); return(vdro.Success); } catch (VaultInternalErrorException e) { if (e.Message.Contains("already exists")) { return(false); } else { throw e; } } }
/// <summary> /// Generates random bytes. Can return data as string or Hexidecimal. Note, Vault native function returns Base64-encoded. This routine /// decodes it before returning to you. /// </summary> /// <param name="numBytes">Number of bytes you need.</param> /// <param name="hexOutputFormat">true if you want hexidecimal values, False if you want ascii</param> /// <returns></returns> public async Task <string> GenerateRandomBytes(int numBytes, bool hexOutputFormat = false) { string path = MountPointPath + "random/" + numBytes.ToString(); // Setup Post Parameters in body. Dictionary <string, string> contentParams = new Dictionary <string, string>(); string encodeFormat = "base64"; if (hexOutputFormat) { encodeFormat = "hex"; } contentParams.Add("format", encodeFormat); VaultDataResponseObjectB vdro = await ParentVault._httpConnector.PostAsync_B(path, "GenerateRandomBytes", contentParams); if (vdro.Success) { string bytes = await vdro.GetDotNetObject <string>("data.random_bytes"); if (hexOutputFormat) { return(bytes); } else { return(VaultUtilityFX.Base64DecodeAscii(bytes)); } } return(""); }
/// <summary> /// Deletes the given key. /// </summary> /// <param name="keyName">The key to delete.</param> /// <returns>True if deletion successful. /// False if the key does not allow deletion because its deletion_allowed config parameters is not set to true. /// Throws VaultInvalidDataException with message of "could not delete policy; not found.</returns> public async Task <bool> DeleteKey(string keyName) { string path = MountPointPath + "keys/" + keyName; try { VaultDataResponseObjectB vdro = await ParentVault._httpConnector.DeleteAsync(path, "DeleteKey"); if (vdro.Success) { return(true); } else { return(false); } } catch (VaultInvalidDataException e) { // Search for the error message - it indicates whether it is key could not be found or deletion not allowed. if (e.Message.Contains("could not delete policy; not found")) { throw e; } if (e.Message.Contains("deletion is not allowed for this policy")) { return(false); } // not sure - rethrow error. throw e; } catch (Exception e) { throw e; } }
// ============================================================================================================================================== /// <summary> /// Re-encrypts the currently encrypted data with the current version of the key. This is a simplified way /// of upgrading the encryption for an element without have to call Decrypt and then Encrypt separately. /// </summary> /// <param name="keyName">The Encryption key to use to decrypt and re-encrypt the data</param> /// <param name="encryptedData">The currently encrypted data element that you want to have upgraded with the new encryption key.</param> /// <param name="keyDerivationContext">The context used for key derivation if the key supports that key derivation.</param> /// <param name="keyVersion">Version of the key to use. Defaults to current version (0).</param> /// <returns>The data element encrypted with the version of the key specified. (Default is latest version of the key). Returns null if operation failed.</returns> public async Task <TransitEncryptedItem> ReEncrypt(string keyName, string encryptedData, string keyDerivationContext = "", int keyVersion = 0) { string path = MountPointPath + "rewrap/" + keyName; // Setup Post Parameters in body. Dictionary <string, string> contentParams = new Dictionary <string, string>(); // Build the parameter list. contentParams.Add("ciphertext", encryptedData); if (keyDerivationContext != "") { contentParams.Add("context", VaultUtilityFX.Base64EncodeAscii(keyDerivationContext)); } if (keyVersion > 0) { contentParams.Add("key_version", keyVersion.ToString()); } VaultDataResponseObjectB vdro = await ParentVault._httpConnector.PostAsync_B(path, "ReEncrypt", contentParams); if (vdro.HttpStatusCode == 200) { return(await vdro.GetDotNetObject <TransitEncryptedItem>()); } else { return(null); } }
// ============================================================================================================================================== /// <summary> /// Decrypts a single encrypted value. If the keys supports convergent or derived encryption then you must supply the keyDerivationContext param. /// </summary> /// <param name="keyName">Name of the encryption key to use to decrypt.</param> /// <param name="encryptedData">The encrypted value that you wish to have decrypted.</param> /// <param name="keyDerivationContext">The context value that is required to delete a convergent encrypted item.</param> /// <returns>TransitDecryptedItem if the value was able to be successfully decrypted. /// Throws <VaultInvalidDataException> if unable to decrypt the item due to bad key or context value.</VaultInvalidDataException></returns> public async Task <TransitDecryptedItem> Decrypt(string keyName, string encryptedData, string keyDerivationContext = "") { string path = MountPointPath + PathDecrypt + keyName; // Setup Post Parameters in body. Dictionary <string, string> contentParams = new Dictionary <string, string>(); // Build the parameter list. contentParams.Add("ciphertext", encryptedData); if (keyDerivationContext != "") { contentParams.Add("context", VaultUtilityFX.Base64EncodeAscii(keyDerivationContext)); } // Call Vault API. VaultDataResponseObjectB vdro = await ParentVault._httpConnector.PostAsync_B(path, "Decrypt", contentParams); if (vdro.HttpStatusCode == 200) { return(await vdro.GetDotNetObject <TransitDecryptedItem>()); } // This code should never get hit. throw new VaultUnexpectedCodePathException("TransitBackEnd-Decrypt"); }
/// <summary> /// Permanently deletes a given secret version. This is unable to be undone. /// </summary> /// <param name="secretNamePath">The secret name to be undeleted.</param> /// <param name="version">The specific version of the secret to be unnamed.</param> /// <returns>True if successful. False otherwise.</returns> public async Task <bool> DestroySecretVersion(string secretNamePath, int version) { try { // V2 Secret stores have a unique destroy path... string path = MountPointPath + "destroy/" + secretNamePath; // Build the content parameters, which will contain the maxVersions and casRequired settings. Dictionary <string, string> contentParams = new Dictionary <string, string>(); contentParams.Add("versions", version.ToString()); VaultDataResponseObjectB vdro = await ParentVault._httpConnector.PostAsync_B(path, "DestroySecretVersion", contentParams); return(vdro.Success); } catch (VaultForbiddenException e) { if (e.Message.Contains("* permission denied")) { e.SpecificErrorCode = EnumVaultExceptionCodes.PermissionDenied; } throw e; } }
/// <summary> /// Generates and issues a new SecretID on an existing AppRole. /// Similar to tokens, the response will also contain a secret_id_accessor value which can be used to read the properties of the SecretID /// without divulging the SecretID itself, and also to delete the SecretID from the AppRole. /// Returns: AppRoleSecret representing the a secret ID Vault returned OR Null if it could not create the secret. /// </summary> /// <param name="appRoleName">Name of the AppRole to create a secret for.</param> /// <param name="metadata">Metadata to be tied to the SecretID. This should be a JSON-formatted string containing the metadata in key-value pairs. /// This metadata will be set on tokens issued with this SecretID, and is logged in audit logs in plaintext.</param> /// <param name="cidrIPsAllowed">Comma separated string or list of CIDR blocks enforcing secret IDs to be used from specific set of IP addresses. /// If bound_cidr_list is set on the role, then the list of CIDR blocks listed here should be a subset of the CIDR blocks listed on the role.</param> /// <returns>AppRoleSecret representing the a secret ID Vault returned.</returns> public async Task <AppRoleSecret> CreateSecretID(string appRoleName, Dictionary <string, string> metadata = null, List <string> cidrIPsAllowed = null) { string path = MountPointPath + "role/" + appRoleName + "/secret-id"; Dictionary <string, object> contentParams = new Dictionary <string, object>(); if (metadata != null) { string metadataString = JsonConvert.SerializeObject(metadata); contentParams.Add("metadata", metadataString); } if (cidrIPsAllowed != null) { string cidrs = JsonConvert.SerializeObject(cidrIPsAllowed); contentParams.Add("cidr_list", cidrs); } VaultDataResponseObjectB vdro = await ParentVault._httpConnector.PostAsync_B(path, "CreateSecretID", contentParams); if (vdro.Success) { return(await vdro.GetDotNetObject <AppRoleSecret> ("data")); } else { return(null); } }
/// <summary> /// Returns a Token object of the Token that is currently being used to access Vault with. This routine also exists within the VaultAuthentication Backend. /// </summary> /// <remarks>This routine and the one in VaultAuthenticationBackend should be kept in sync.</remarks> /// <returns>Token object of the current token used to access Vault Instance with.</returns> public async Task <Token> GetCurrentTokenInfo() { string path = MountPointPath + "lookup-self"; try { VaultDataResponseObjectB vdro = await ParentVault._httpConnector.GetAsync_B(path, "GetCurrentTokenInfo"); if (vdro.Success) { return(await vdro.GetDotNetObject <Token>()); } else { throw new VaultUnexpectedCodePathException(); } } // If Vault is telling us it is a bad token, then return null. catch (VaultForbiddenException e) { if (e.Message.Contains("bad token")) { return(null); } else { throw e; } } }
/// <summary> /// Revokes the token associated with a given accessor AND all child tokens. Meant for purposes where there is no access to the token, but there is a need to revoke it. /// </summary> /// <param name="AccessorID">The ID of the accessor token that has access to the token you wish to revoke.</param> /// <returns>True if the token was revoked. False if the token could not be found.</returns> public async Task <bool> RevokeTokenViaAccessor(string AccessorID) { string path = MountPointPath + "revoke-accessor"; Dictionary <string, object> contentParams = new Dictionary <string, object>() { { "accessor", AccessorID } }; try { VaultDataResponseObjectB vdro = await ParentVault._httpConnector.PostAsync_B(path, "RevokeTokenViaAccessor", contentParams); if (vdro.Success) { return(true); } else { throw new VaultUnexpectedCodePathException(); } } catch (VaultInvalidDataException e) { if (e.Message.Contains("invalid accessor")) { return(false); } throw e; } }
/* * Methods to be implemented: * - Create Entity - Implemented (SaveEntity) * - Read Entity by ID - Implemented (ReadEntity) * - Update Entity by ID - Implemented (SaveEntity) * - Delete Entity by ID - Implemented (DeleteEntity) * - List Entities by ID - Implemented (ListEntitiesByID) * - Create / Update Entity by Name - Not Implemented * - Read Entity by Name - Implemented * - Delete Entity by Name - Implemented * - List Entities by Name - Implemented * - Merge Entities - Not Implemented */ #region "Core Entity Methods" /// <summary> /// Saves the given entity to the Database. If an Entity ID is provided it will update the entry. Otherwise a new entity will be /// created. It returns Null if the save failed for some reason. Otherwise returns an Entity object. /// </summary> /// <param name="entity"></param> /// <returns></returns> public async Task <Entity> SaveEntity(Entity entity) { string path = MountPointPath + "entity"; string json = JsonConvert.SerializeObject(entity); VaultDataResponseObjectB vdro = await ParentVault._httpConnector.PostAsync_B(path, "IdentityEngine: SaveEntity", json); if (vdro.Success) { Guid guid; // If this was an update (Non empty Guid) then Vault for some reason does not return anything. So we need to get the GUID from the // passed in Entity object. Otherwise it is in the response body. if (entity.Id != Guid.Empty) { guid = entity.Id; } else { string id = await vdro.GetDotNetObject <string>("data.id"); guid = new Guid(id); } Entity entityNew = await ReadEntity(guid); // TODO - Read the Entity back from the DB and return to user. return(entityNew); } return(null); }
/// <summary> /// Updates the given Alias (ID) with the specified mountAccessor and aliasName. /// </summary> /// <param name="aliasID">The alias ID to be updated with new values.</param> /// <param name="entityID">The ID of the entity to which this Alias belongs.</param> /// <param name="mountAccessor">The authentication backend mount accessor the alias belongs to.</param> /// <param name="aliasName">Name of the authentication backend user to associate with this alias.</param> /// <returns></returns> public async Task <Guid> UpdateAlias(Guid aliasID, Guid entityID, string mountAccessor, string aliasName) { string path = MountPointPath + "entity-alias/id/" + aliasID; Dictionary <string, string> contentParams = new Dictionary <string, string>() { { "name", aliasName }, { "canonical_id", entityID.ToString() }, { "mount_accessor", mountAccessor } }; VaultDataResponseObjectB vdro = await ParentVault._httpConnector.PostAsync_B(path, "IdentityEngine: UpdateAlias", contentParams); if (vdro.Success) { string id = await vdro.GetDotNetObject <string>("data.id"); //vdro.GetDataPackageFieldAsJSON ("id"); Guid guid = new Guid(id); return(guid); } else { return(Guid.Empty); } }
/// <summary> /// Creates / Saves a token role. /// </summary> /// <param name="tokenRole">The TokenRole object that contains the Token Role to be created / updated.</param> /// <returns>True if token Role was successfully created.</returns> public async Task <bool> SaveTokenRole(TokenRole tokenRole) { string path = MountPointPath + "roles/" + tokenRole.Name; string json = JsonConvert.SerializeObject(tokenRole, Formatting.None); try { VaultDataResponseObjectB vdro = await ParentVault._httpConnector.PostAsync_B(path, "SaveTokenRole", json); if (vdro.Success) { return(true); } else { throw new VaultUnexpectedCodePathException(); } } catch (VaultInvalidDataException e) { if (e.Message.Contains("invalid accessor")) { return(false); } throw e; } }
/// <summary> /// Provides a list of all the secret ID accessors that are attached to a given role. /// </summary> /// <param name="roleName">The Rolename to list the secret ID accessors for.</param> /// <returns>List of secret ID accessors for a given role.</returns> public async Task <List <string> > ListSecretIDAccessors(string roleName) { string path = MountPointPath + "role/" + roleName + "/secret-id"; try { // Setup List Parameter Dictionary <string, string> contentParams = new Dictionary <string, string>() { { "list", "true" } }; VaultDataResponseObjectB vdro = await ParentVault._httpConnector.GetAsync_B(path, "ListSecretIDAccessors", contentParams); if (vdro.Success) { List <string> keys = await vdro.GetDotNetObject <List <string> > ("data.keys"); /* * string js = vdro.GetJSONPropertyValue (vdro.GetDataPackageAsJSON(), "keys"); * List<string> keys = VaultUtilityFX.ConvertJSON<List<string>> (js); */ return(keys); } throw new ApplicationException("AppRoleAuthEngine:ListRoles -> Arrived at unexpected code block."); } // 404 Errors mean there were no roles. We just return an empty list. catch (VaultInvalidPathException) { return(new List <string>()); } }
/// <summary> /// Returns all the properties of a given secretID for a given role. Returns null if the secretID could not be found. /// </summary> /// <param name="roleName">The name of the role that the secretID belongs to.</param> /// <param name="secretID">The specific secretID to retrieve information on.</param> /// <returns>The properties of the secretID</returns> public async Task <AppRoleSecret> ReadSecretID(string roleName, string secretID) { string path = MountPointPath + "role/" + roleName + "/secret-id/lookup"; // Setup secret ID Parameter Dictionary <string, object> contentParams = new Dictionary <string, object>() { { "secret_id", secretID } }; try { VaultDataResponseObjectB vdro = await ParentVault._httpConnector.PostAsync_B(path, "ReadSecretID", contentParams); // Note: We cannot test for HTTP Success as Vault returns a 204 if secretID is not found - might be a bug - filed a post on Forum. // TODO - Follow up to see if this is a bug or feature. if (vdro.HttpStatusCode == 200) { AppRoleSecret secret = await vdro.GetDotNetObject <AppRoleSecret>(); // We need to do this as Vault does NOT return the ID of the secret in the data. // TODO - Do we want to blank it out or continue filling it in....? secret.ID = secretID; return(secret); } else { return(null); } } catch (VaultInvalidPathException e) { e.SpecificErrorCode = EnumVaultExceptionCodes.ObjectDoesNotExist; throw e; } }
/// <summary> /// Returns a list of the LDAP groups that Vault has policies for. Please note, this is not all the groups in the LDAP Backend. If no /// groups found it returns an empty List. /// </summary> /// <returns></returns> public async Task <List <string> > ListGroups() { string path = MountPointPath + "groups"; try { // Setup List Parameter Dictionary <string, string> contentParams = new Dictionary <string, string>() { { "list", "true" } }; VaultDataResponseObjectB vdro = await ParentVault._httpConnector.GetAsync_B(path, "LdapAuthEngine:ListUsers", contentParams); if (vdro.Success) { return(await vdro.GetDotNetObject <List <string> > ("data.keys")); } throw new ApplicationException("LdapAuthEngine:ListUsers -> Arrived at unexpected code block."); } // 404 Errors mean there were no roles. We just return an empty list. catch (VaultInvalidPathException) { return(new List <string>()); } }
/// <summary> /// Retrieves the requested token. Returns Null if the token could not be found. /// </summary> /// <param name="tokenID">The ID of the token to retrieve.</param> /// <returns>Token object of the requested token or null if the token is invalid. Will throw error for other issues.</returns> public async Task <Token> GetTokenWithID(string tokenID) { string path = MountPointPath + "lookup"; Dictionary <string, object> contentParams = new Dictionary <string, object>() { { "token", tokenID } }; try { VaultDataResponseObjectB vdro = await ParentVault._httpConnector.PostAsync_B(path, "GetToken", contentParams); if (vdro.Success) { return(await vdro.GetDotNetObject <Token>()); } else { throw new VaultUnexpectedCodePathException(); } } // If Vault is telling us it is a bad token, then return null. catch (VaultForbiddenException e) { if (e.Message.Contains("bad token")) { return(null); } else { throw e; } } }
/// <summary> /// Deletes an EntityAlias. Returns true on success. /// </summary> /// <param name="id">The Id of the entityAlias to be deleted.</param> /// <returns></returns> public async Task <bool> DeleteAlias(Guid id) { string path = MountPointPath + "entity-alias/id/" + id; VaultDataResponseObjectB vdro = await ParentVault._httpConnector.DeleteAsync(path, "DeleteEntityAlias"); return(vdro.Success ? true : false); }
/// <summary> /// Deletes an Entity and all of it's associated aliases. Returns True if successful. Will also return True if the name passed in does not /// exist in the Vault Database. /// </summary> /// <param name="entityName">The name of the entity to be deleted.</param> /// <returns></returns> public async Task <bool> DeleteEntity(string entityName) { string path = MountPointPath + "entity/name/" + entityName; VaultDataResponseObjectB vdro = await ParentVault._httpConnector.DeleteAsync(path, "DeleteEntity (EntityName)"); return(vdro.Success ? true : false); }
// ============================================================================================================================================== /// <summary> /// Reads the Encrypted Key specified /// </summary> /// <param name="keyName">The name of the key to read</param> /// <returns></returns> public async Task <TransitKeyInfo> ReadEncryptionKey(string keyName) { // The keyname forms the last part of the path string path = MountPointPath + PathKeys + keyName; VaultDataResponseObjectB vdro = await ParentVault._httpConnector.GetAsync_B(path, "ReadEncryptionKey"); return(await vdro.GetDotNetObject <TransitKeyInfo>()); }
/// <summary> /// Sets the configuration for the given LDAP Backend. The configuration is everything need to setup an LDAP connection. /// </summary> /// <param name="ldapConfig">The LdapConfig object that contains all the LDAP connection information.</param> /// <returns></returns> public async Task <bool> ConfigureLDAPBackend(LdapConfig ldapConfig) { string path = MountPointPath + "config"; string json = JsonConvert.SerializeObject(ldapConfig); VaultDataResponseObjectB vdro = await ParentVault._httpConnector.PostAsync_B(path, "LdapAuthEngine: ConfigureLDAPBackend", json, false); return(vdro.Success); }
/// <summary> /// Retrieves the AppRoleID of the given AppRole. /// </summary> /// <param name="appRoleName"></param> /// <returns>Returns a string representing the Role ID as stored in Vault. Returns RoleID as empty string if RoleID could not be found. /// VaultInvalidPathException with SpecificErrorCode = ObjectDoesNotExist, if the Role does not exist. /// </returns> public async Task <string> ReadRoleID(string appRoleName) { string path = MountPointPath + "role/" + appRoleName + "/role-id"; try { VaultDataResponseObjectB vdro = await ParentVault._httpConnector.GetAsync_B(path, "ReadRoleID"); return(vdro.Success ? await vdro.GetDotNetObject <string> ("data.role_id") : ""); } catch (VaultInvalidPathException) { return(""); } }
/// <summary> /// Reads the secret from Vault. It defaults to reading the most recent version. Set secretVersion to non zero to /// retrieve a /// specific version. /// <para>Returns [VaultForbiddenException] if you do not have permission to read from the path.</para> /// <para>Returns the IKV2SecretWrapper if a secret was found at the location.</para> /// <para>Returns Null if no secret found at location.</para> /// </summary> /// <param name="secretPath">The Name (path) to the secret you wish to read.</param> /// <param name="secretVersion">The version of the secret to retrieve. (Default) set to 0 to read most recent version. </param> /// <returns>IKV2Secret of the secret as read from Vault. Returns null if there is no secret at that path.</returns> public async Task <T> ReadSecret <T>(string secretPath, int secretVersion = 0) where T : KV2SecretBase <T> { string path = MountPointPath + "data/" + secretPath; Dictionary <string, string> contentParams = new Dictionary <string, string>(); // TODO - Read secret will return an object for a version that has been destroyed or deleted. We need to interrogate that // and try and find the next non deleted version. try { if (secretVersion > 0) { contentParams.Add("version", secretVersion.ToString()); } VaultDataResponseObjectB vdro = await ParentVault._httpConnector.GetAsync_B(path, "ReadSecret", contentParams); if (vdro.Success) { KV2SecretWrapper <T> secretReadReturnObj = await vdro.GetDotNetObject <KV2SecretWrapper <T> >(""); // We now need to move some fields from the IKV2SecretWrapper into the IKV2Secret which is embedded in the // wrapper class. secretReadReturnObj.Secret.CreatedTime = secretReadReturnObj.Data.Metadata.CreatedTime; secretReadReturnObj.Secret.DeletionTime = (DateTimeOffset)secretReadReturnObj.Data.Metadata.DeletionTime; secretReadReturnObj.Secret.IsDestroyed = secretReadReturnObj.Data.Metadata.Destroyed; secretReadReturnObj.Secret.Version = secretReadReturnObj.Data.Metadata.Version; // Now get the secret obj, remove it from the wrapper - so the class can be deleted and then return to caller. T secret = secretReadReturnObj.Secret; secretReadReturnObj.Secret = null; return(secret); } throw new ApplicationException("SecretBackEnd: ReadSecret - Arrived at an unexpected code path."); } // VaultInvalidPathExceptions are not permission problems - despite what the error text hints at. Instead they just mean no secret exists at that path. We return null. catch (VaultInvalidPathException) { return(null); } catch (VaultForbiddenException e) { if (e.Message.Contains("* permission denied")) { e.SpecificErrorCode = EnumVaultExceptionCodes.PermissionDenied; } throw e; } }
/// <summary> /// Reads the LDAP Config that corresponds to this engine. Returns the JSON representation of the config. /// </summary> /// <returns></returns> public async Task <string> ReadLDAPConfigAsJSON() { string path = MountPointPath + "config"; VaultDataResponseObjectB vdro = await ParentVault._httpConnector.GetAsync_B(path, "ReadLDAPConfigAsJSON"); if (vdro.Success) { return(await vdro.GetJSON()); } return(null); }
/// <summary> /// Updates the AppRoleID of the given AppRole to the value specified. /// </summary> /// <param name="appRoleName"></param> /// <param name="valueOfRoleID"></param> /// <returns>True if update of RoleID was successful.</returns> public async Task <bool> UpdateAppRoleID(string appRoleName, string valueOfRoleID) { string path = MountPointPath + "role/" + appRoleName + "/role-id"; Dictionary <string, object> contentParams = new Dictionary <string, object>() { { "role_id", valueOfRoleID } }; VaultDataResponseObjectB vdro = await ParentVault._httpConnector.PostAsync_B(path, "UpdateAppRoleID", contentParams); return(vdro.HttpStatusCode == 204 ? true : false); }
/// <summary> /// Returns a List of Roles assigned to the Token /// </summary> /// <returns></returns> public async Task <List <string> > ListTokenRoles() { string path = MountPointPath + "roles?list=true"; VaultDataResponseObjectB vdro = await ParentVault._httpConnector.GetAsync_B(path, "ListTokenRoles"); if (vdro.Success) { return(await vdro.GetDotNetObject <List <string> >("data.keys")); } return(null); }
/// <summary> /// Returns a List of Encryption keys /// </summary> /// <returns></returns> public async Task <List <string> > ListEncryptionKeys() { string path = MountPointPath + PathKeys; // Setup List Parameter Dictionary <string, string> sendParams = new Dictionary <string, string>(); sendParams.Add("list", "true"); VaultDataResponseObjectB vdro = await ParentVault._httpConnector.GetAsync_B(path, "ListEncryptionKeys", sendParams); return(await vdro.GetDotNetObject <List <string> >("data.keys")); }
/// <summary> /// Reads the alias with the associated ID from the Identity store. Returns an EntityAlias of the read object. /// <para>[VaultInvalidDataPath] - returns this exception if it could not find the requested value.</para> /// </summary> /// <param name="aliasID"></param> /// <returns></returns> public async Task <EntityAlias> ReadAlias(Guid aliasID) { string path = MountPointPath + "entity-alias/id/" + aliasID; VaultDataResponseObjectB vdro = await ParentVault._httpConnector.GetAsync_B(path, "IdentityEngine: ReadAlias (AliasID)", null); if (vdro.Success) { return(await vdro.GetDotNetObject <EntityAlias>()); } return(null); }
/// <summary> /// Reads the requested Entity from the Vault. Returns Entity object on success. /// <para>Throws [VaultInvalidPathException] if the entity was not found.</para> /// </summary> /// <param name="id">The GUID ID value of the entity to retrieve.</param> /// <returns></returns> public async Task <Entity> ReadEntity(Guid id) { string path = MountPointPath + "entity/id/" + id; VaultDataResponseObjectB vdro = await ParentVault._httpConnector.GetAsync_B(path, "IdentityEngine: ReadEntity", null); if (vdro.Success) { return(await vdro.GetDotNetObject <Entity>()); } return(null); }
/// <summary> /// Logs the given secretID into the Application Role identified by RoleID. RoleID is always required; if bind_secret_id is enabled (the default) on the AppRole, secretID is required also. /// Returns a populated Token object if successfull. Returns Null if it failed due to invalid Role or Secret ID /// </summary> /// <param name="roleID">Required: The RoleID value that you wish to login to.</param> /// <param name="secretID">Optional: The secretID to use to login to the role with.</param> /// <returns>Token object that was created, that can be used to access the Vault with. The parent token has also been set to this same token.</returns> /// TODO - Change the return type. public async Task <Token> Login(string roleID, string secretID) { string path = MountPointPath + "login"; // Setup roleID and secret ID Parameters Dictionary <string, string> contentParams = new Dictionary <string, string>() { { "role_id", roleID }, { "secret_id", secretID } }; try { VaultDataResponseObjectB vdro = await ParentVault._httpConnector.PostAsync_B(path, "Login", contentParams); // Now convert the JSON returned by Vault into a LoginResponse object and then get the Client ID token value out of it. LoginResponse loginResponse = await vdro.GetDotNetObject <LoginResponse> ("auth"); //TODO - CLeanup //string js = vdro.GetResponsePackageFieldAsJSON ("auth"); //LoginResponse loginResponse = VaultUtilityFX.ConvertJSON<LoginResponse> (js); // We need to set the token and then refresh it. ParentVault.TokenID = loginResponse.ClientToken; await ParentVault.RefreshActiveToken(); return(ParentVault.Token); } catch (VaultInvalidDataException e) { // This means the secret ID is incorrect. if (e.Message.Contains("missing secret_id")) { VaultInvalidDataException newEx = new VaultInvalidDataException( "The secret ID supplied is either not a valid Secret ID or it is not associated with the RoleID supplied. The secretID must be valid and it must be associated with the provided RoleID.", e); newEx.SpecificErrorCode = EnumVaultExceptionCodes.LoginSecretID_NotFound; throw newEx; } // RoleID is incorrect. else if (e.Message.Contains("missing role_id")) { VaultInvalidDataException newEx = new VaultInvalidDataException("The RoleID supplied is invalid. The RoleID must exist in the Vault.", e); newEx.SpecificErrorCode = EnumVaultExceptionCodes.LoginRoleID_NotFound; throw newEx; } throw e; } }
/// <summary> /// Generates a secret ID for a given Application Role. /// TODO - At this time this method does not support the cidr_list or token_bound_cidrs properties that restrict the IP addresses that can use a given token. /// </summary> /// <param name="appRoleName">The name of the Application Role that you wish to generate a Secret ID For</param> /// <param name="returnFullSecret">Vault only returns an abbreviated secret object. If you wish to have a fully populated one then set to true. Default False. /// Note, that this in no way affects the secret itself. By setting to true, we make an additional call to Vault to re-read the full secret object. If you do not /// need the full secret information then leaving at false is faster.</param> /// <param name="vaultMetadata">A Vault MetaData object that should be attached to the given secret. </param> /// <returns>AppRoleSecret object. Whether this is fully populated or contains just the ID and accessor depends upon the returnFullSecret parameter.</returns> public async Task <AppRoleSecret> GenerateSecretID(string appRoleName, bool returnFullSecret = false, Dictionary <string, string> vaultMetadata = null) { string path = MountPointPath + "role/" + appRoleName + "/secret-id"; Dictionary <string, object> contentParams = new Dictionary <string, object>(); if (vaultMetadata != null) { string metadataString = JsonConvert.SerializeObject(vaultMetadata); contentParams.Add("metadata", metadataString); } /* if (cidrIPsAllowed != null) { * string cidrs = JsonConvert.SerializeObject(cidrIPsAllowed); * contentParams.Add("cidr_list", cidrs); * } */ try { VaultDataResponseObjectB vdro = await ParentVault._httpConnector.PostAsync_B(path, "GenerateSecretID", contentParams); if (vdro.Success) { AppRoleSecret appRoleSecret = await vdro.GetDotNetObject <AppRoleSecret> ("data"); if (returnFullSecret) { AppRoleSecret fullSecret = await ReadSecretID(appRoleName, appRoleSecret.ID); return(fullSecret); } else { return(appRoleSecret); } } else { return(null); } } catch (VaultInvalidPathException e) { if (e.Message.Contains("role") && e.Message.Contains("does not exist")) { e.SpecificErrorCode = EnumVaultExceptionCodes.ObjectDoesNotExist; } throw e; } }