/// <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; } }