/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2020 Dominik Reichl This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Text; namespace ModernKeePassLib.Cryptography.Cipher { /// /// Pool of encryption/decryption algorithms (ciphers). /// public sealed class CipherPool { private List m_lCiphers = new List(); private static CipherPool m_poolGlobal = null; public static CipherPool GlobalPool { get { CipherPool cp = m_poolGlobal; if(cp == null) { cp = new CipherPool(); cp.AddCipher(new StandardAesEngine()); cp.AddCipher(new ChaCha20Engine()); m_poolGlobal = cp; } return cp; } } /// /// Remove all cipher engines from the current pool. /// public void Clear() { m_lCiphers.Clear(); } /// /// Add a cipher engine to the pool. /// /// Cipher engine to add. Must not be null. public void AddCipher(ICipherEngine c) { if(c == null) { Debug.Assert(false); throw new ArgumentNullException("c"); } // Return if a cipher with that ID is registered already foreach(ICipherEngine cEx in m_lCiphers) { if(cEx.CipherUuid.Equals(c.CipherUuid)) return; } m_lCiphers.Add(c); } /// /// Get a cipher identified by its UUID. /// /// UUID of the cipher to return. /// Reference to the requested cipher. If the cipher is /// not found, null is returned. public ICipherEngine GetCipher(PwUuid uuidCipher) { foreach(ICipherEngine c in m_lCiphers) { if(c.CipherUuid.Equals(uuidCipher)) return c; } return null; } /// /// Get the index of a cipher. This index is temporary and should /// not be stored or used to identify a cipher. /// /// UUID of the cipher. /// Index of the requested cipher. Returns -1 if /// the specified cipher is not found. public int GetCipherIndex(PwUuid uuidCipher) { for(int i = 0; i < m_lCiphers.Count; ++i) { if(m_lCiphers[i].CipherUuid.Equals(uuidCipher)) return i; } Debug.Assert(false); return -1; } /// /// Get the index of a cipher. This index is temporary and should /// not be stored or used to identify a cipher. /// /// Name of the cipher. Note that /// multiple ciphers can have the same name. In this case, the /// first matching cipher is returned. /// Cipher with the specified name or -1 if /// no cipher with that name is found. public int GetCipherIndex(string strDisplayName) { for(int i = 0; i < m_lCiphers.Count; ++i) { if(m_lCiphers[i].DisplayName == strDisplayName) return i; } Debug.Assert(false); return -1; } /// /// Get the number of cipher engines in this pool. /// public int EngineCount { get { return m_lCiphers.Count; } } /// /// Get the cipher engine at the specified position. Throws /// an exception if the index is invalid. You can use this /// to iterate over all ciphers, but do not use it to /// identify ciphers. /// /// Index of the requested cipher engine. /// Reference to the cipher engine at the specified /// position. public ICipherEngine this[int nIndex] { get { if((nIndex < 0) || (nIndex >= m_lCiphers.Count)) throw new ArgumentOutOfRangeException("nIndex"); return m_lCiphers[nIndex]; } } } }