예제 #1
0
        /// <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;
                }
            }
        }
예제 #2
0
        /// <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("");
        }
예제 #3
0
        /// <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; }
        }
예제 #4
0
        // ==============================================================================================================================================
        /// <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);
            }
        }
예제 #5
0
        // ==============================================================================================================================================
        /// <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");
        }
예제 #6
0
        /// <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;
            }
        }
예제 #7
0
        /// <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);
            }
        }
예제 #8
0
        /// <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;
                }
            }
        }
예제 #9
0
        /// <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;
            }
        }
예제 #10
0
        /*
         * 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);
        }
예제 #11
0
        /// <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);
            }
        }
예제 #12
0
        /// <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;
            }
        }
예제 #13
0
        /// <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>()); }
        }
예제 #14
0
        /// <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;
            }
        }
예제 #15
0
        /// <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>());
            }
        }
예제 #16
0
        /// <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;
                }
            }
        }
예제 #17
0
        /// <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);
        }
예제 #18
0
        /// <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);
        }
예제 #19
0
        // ==============================================================================================================================================
        /// <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>());
        }
예제 #20
0
        /// <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);
        }
예제 #21
0
        /// <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(""); }
        }
예제 #22
0
        /// <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;
            }
        }
예제 #23
0
        /// <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);
        }
예제 #24
0
        /// <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);
        }
예제 #25
0
        /// <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);
        }
예제 #26
0
        /// <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"));
        }
예제 #27
0
        /// <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);
        }
예제 #28
0
        /// <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);
        }
예제 #29
0
        /// <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;
            }
        }
예제 #30
0
        /// <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;
            }
        }