/// <summary> /// For use only when decrypting a volume member. /// <para>Resets the Expired flag; useage must guarantee that the same key-to-file matching is used when re-encrypting the file.</para> /// </summary> /// /// <param name="KeyId">The unique subkey id</param> public void ResetSubKeyFlag(byte[] KeyId) { if (AccessScope.Equals(KeyScope.NoAccess)) { throw new CryptoProcessingException("PackageFactory:Extract", "You do not have permission to access this key!", new UnauthorizedAccessException()); } try { long keyPos; int index; // get the key data MemoryStream keyStream = GetKeyStream(); // get the keying materials starting offset within the key file keyPos = PackageKey.SubKeyOffset(keyStream, KeyId); if (keyPos == -1) { throw new CryptoProcessingException("PackageFactory:Extract", "This package does not contain the key file!", new ArgumentException()); } // get the index index = PackageKey.IndexFromId(keyStream, KeyId); PackageKey.SubKeyClearPolicy(keyStream, index, (long)PackageKeyStates.Expired); // write to file WriteKeyStream(keyStream); } catch { throw; } }
/// <summary> /// Test a PackageKey subkey for expired status /// </summary> /// /// <param name="KeyId">The subkey id to test</param> /// /// <returns>Returns true if subkey has expired and can not be used for encryption, false if a valid key</returns> /// /// <exception cref="CryptoProcessingException">Thrown if the user has insufficient access rights to access this PackageKey</exception> public bool HasExpired(byte[] KeyId) { if (AccessScope.Equals(KeyScope.NoAccess)) { throw new CryptoProcessingException("PackageFactory:HasExpired", "You do not have permission to access this key!", new UnauthorizedAccessException()); } int index = ContainsSubKey(KeyId); if (index < 0) { return(true); } return(PackageKey.KeyHasPolicy(m_keyPackage.SubKeyPolicy[index], (int)PackageKeyStates.Expired)); }
/// <summary> /// Test a key to see if it contains a subkey with a specific id /// </summary> /// /// <param name="KeyId">The subkey id to test</param> /// /// <returns>The index of the subkey, or -1 if key is not in the PackageKey</returns> /// /// <exception cref="CryptoProcessingException">Thrown if the user has insufficient access rights to access this PackageKey</exception> public int ContainsSubKey(byte[] KeyId) { if (AccessScope.Equals(KeyScope.NoAccess)) { throw new CryptoProcessingException("PackageFactory:ContainsSubKey", "You do not have permission to access this key!", new UnauthorizedAccessException()); } for (int i = 0; i < m_keyPackage.SubKeyID.Length; i++) { if (Compare.IsEqual(KeyId, m_keyPackage.SubKeyID[i])) { return(i); } } return(-1); }
/// <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; } }
/// <summary> /// Test the PackageKey for remaining valid subkeys /// </summary> /// /// <returns>PackageKey contains subkeys that are valid for encryption</returns> /// /// <exception cref="CryptoProcessingException">Thrown if the user has insufficient access rights to access this PackageKey</exception> public bool HasExpired() { if (AccessScope.Equals(KeyScope.NoAccess)) { throw new CryptoProcessingException("PackageFactory:HasExpired", "You do not have permission to access this key!", new UnauthorizedAccessException()); } for (int i = 0; i < m_keyPackage.SubKeyCount; i++) { if (!PackageKey.KeyHasPolicy(m_keyPackage.SubKeyPolicy[i], (long)PackageKeyStates.Expired)) { return(false); } } return(true); }
/// <summary> /// Get information about the key file in the form of an <see cref="PackageInfo"/> structure /// </summary> /// /// <returns>A <see cref="PackageInfo"/> structure</returns> /// /// <exception cref="CryptoProcessingException">Thrown if the user has insufficient access rights to access this PackageKey</exception> public PackageInfo KeyInfo() { if (AccessScope.Equals(KeyScope.NoAccess)) { throw new CryptoProcessingException("PackageFactory:KeyInfo", "You do not have permission to access this key!", new UnauthorizedAccessException()); } PackageInfo info = new PackageInfo(m_keyPackage); // return limited data if (PackageKey.KeyHasPolicy(KeyPolicy, (long)KeyPolicies.NoNarrative)) { info.Origin = Guid.Empty; info.Policies.Clear(); } return(info); }
/// <summary> /// For use only when decrypting a volume member. /// <para>Resets the Expired flag; useage must guarantee that the same key-to-file matching is used when re-encrypting the file.</para> /// </summary> /// /// <param name="Index">The subkey index</param> public void ResetSubKeyFlag(int Index) { if (AccessScope.Equals(KeyScope.NoAccess)) { throw new CryptoProcessingException("PackageFactory:Extract", "You do not have permission to access this key!", new UnauthorizedAccessException()); } try { // get the key data MemoryStream keyStream = GetKeyStream(); PackageKey.SubKeyClearPolicy(keyStream, Index, (long)PackageKeyStates.Expired); // write to file WriteKeyStream(keyStream); } catch { throw; } }
/// <summary> /// Get the policy flags for a subkey /// </summary> /// /// <param name="KeyId">Id of the subkey to query</param> /// /// <returns>Sub key policy flag, or -1 if not key id found</returns> /// /// <exception cref="CryptoProcessingException">Thrown if the user has insufficient access rights to access this PackageKey</exception> public long Policy(byte[] KeyId) { if (AccessScope.Equals(KeyScope.NoAccess)) { throw new CryptoProcessingException("PackageFactory:Policy", "You do not have permission to access this key!", new UnauthorizedAccessException()); } int index = ContainsSubKey(KeyId); if (index < 0) { return(-1); } if (index > m_keyPackage.SubKeyPolicy.Length) { return(-1); } return(m_keyPackage.SubKeyPolicy[index]); }
/// <summary> /// Extract a subkey set (KeyParam), a file extension key, and a CipherDescription. /// <para>Used only when calling a Decryption function to get a specific subkey /// The KeyId field corresponds with the KeyId field contained in a MessageHeader structure.</para> /// </summary> /// /// <param name="KeyId">The KeyId array used to identify a subkey set; set as the KeyId in a MessageHeader structure</param> /// <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> /// /// <exception cref="CryptoProcessingException">Thrown if the user has insufficient access rights to access this PackageKey, or the PackageKey does not contain the KeyId specified</exception> public void Extract(byte[] KeyId, out CipherDescription Description, out KeyParams KeyParam) { if (AccessScope.Equals(KeyScope.NoAccess)) { throw new CryptoProcessingException("PackageFactory:Extract", "You do not have permission to access this key!", new UnauthorizedAccessException()); } try { long keyPos; int index; // get the key data MemoryStream keyStream = GetKeyStream(); // get the keying materials starting offset within the key file keyPos = PackageKey.SubKeyOffset(keyStream, KeyId); if (keyPos == -1) { throw new CryptoProcessingException("PackageFactory:Extract", "This package does not contain the key file!", new ArgumentException()); } // get the index index = PackageKey.IndexFromId(keyStream, KeyId); // key flagged SingleUse was used for decryption and is locked out if (PackageKey.KeyHasPolicy(m_keyPackage.SubKeyPolicy[index], (long)PackageKeyStates.Locked) && !PackageKey.KeyHasPolicy(KeyPolicy, (long)KeyPolicies.VolumeKey)) { throw new CryptoProcessingException("PackageFactory:Extract", "SubKey is locked. The subkey has a single use policy and was previously used to decrypt the file.", new Exception()); } // key flagged PostOverwrite was used for decryption and was erased if (PackageKey.KeyHasPolicy(m_keyPackage.SubKeyPolicy[index], (long)PackageKeyStates.Erased)) { throw new CryptoProcessingException("PackageFactory:Extract", "SubKey is erased. The subkey has a post erase policy and was previously used to decrypt the file.", new Exception()); } // get the cipher description Description = m_keyPackage.Description; // get the keying material KeyParam = GetKeySet(keyStream, m_keyPackage.Description, keyPos); // test flags for overwrite or single use policies if (PackageKey.KeyHasPolicy(KeyPolicy, (long)KeyPolicies.PostOverwrite)) { PackageKey.SubKeySetPolicy(keyStream, index, (long)PackageKeyStates.Erased); } else if (PackageKey.KeyHasPolicy(KeyPolicy, (long)KeyPolicies.SingleUse)) { PackageKey.SubKeySetPolicy(keyStream, index, (long)PackageKeyStates.Locked); } // post overwrite flag set, erase the subkey if (PackageKey.KeyHasPolicy(KeyPolicy, (long)KeyPolicies.PostOverwrite)) { int keySize = Description.KeySize + Description.IvSize + Description.MacKeySize; // overwrite the region within file Erase(keyStream, keyPos, keySize); // clear this section of the key keyStream.Seek(keyPos, SeekOrigin.Begin); keyStream.Write(new byte[keySize], 0, keySize); } // write to file WriteKeyStream(keyStream); } catch { throw; } }