Ejemplo n.º 1
0
        /// <summary>
        /// Extract the next valid subkey set (Expired flag not set) as a KeyParam, and a CipherDescription structure.
        /// <para>Used only when calling a Encryption function.</para>
        /// </summary>
        ///
        /// <param name="Description">out: The CipherDescription structure; the properties required to create a specific cipher instance</param>
        /// <param name="KeyParam">out: The KeyParams class containing a unique key, initialization vector and HMAC key</param>
        ///
        /// <returns>The KeyId array used to identify a subkey set; set as the KeyId in a MessageHeader structure</returns>
        ///
        /// <exception cref="CryptoProcessingException">Thrown if the user has insufficient access rights to perform encryption with this key.</exception>
        public byte[] NextKey(out CipherDescription Description, out KeyParams KeyParam)
        {
            if (!AccessScope.Equals(KeyScope.Creator))
            {
                throw new CryptoProcessingException("PackageFactory:NextKey", "You do not have permission to encrypt with this key!", new UnauthorizedAccessException());
            }

            try
            {
                // get the key data
                MemoryStream keyStream = GetKeyStream();
                // get the next unused key for encryption
                int index = PackageKey.NextSubkey(keyStream);

                if (index == -1)
                {
                    throw new CryptoProcessingException("PackageFactory:NextKey", "The key file has expired! There are no keys left available for encryption.", new Exception());
                }

                // get the cipher description
                Description = m_keyPackage.Description;
                // store the subkey identity, this is written into the message header to identify the subkey
                byte[] keyId = m_keyPackage.SubKeyID[index];
                // get the starting position of the keying material within the package
                long keyPos = PackageKey.SubKeyOffset(keyStream, keyId);

                // no unused keys in the package file
                if (keyPos == -1)
                {
                    throw new CryptoProcessingException("PackageFactory:NextKey", "The key file has expired! There are no keys left available for encryption.", new Exception());
                }

                // get the keying material
                KeyParam = GetKeySet(keyStream, m_keyPackage.Description, keyPos);
                // mark the subkey as expired
                PackageKey.SubKeySetPolicy(keyStream, index, (long)PackageKeyStates.Expired);
                // write to file
                WriteKeyStream(keyStream);
                // return the subkey id
                return(keyId);
            }
            catch
            {
                throw;
            }
        }