/// <summary> /// Get the file extension key associated with a subkey /// </summary> /// /// <param name="KeyId">The id of the subkey</param> /// /// <returns>The keys extension array</returns> public byte[] GetExtensionKey(byte[] KeyId) { 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:GetExtensionKey", "This package does not contain the key file!", new ArgumentException()); } // get the index index = PackageKey.IndexFromId(keyStream, KeyId); // key flagged PostOverwrite was used for decryption and was erased if (PackageKey.KeyHasPolicy(m_keyPackage.SubKeyPolicy[index], (long)PackageKeyStates.Erased)) { throw new CryptoProcessingException("PackageFactory:GetExtensionKey", "SubKey is erased. The subkey has a post erase policy and was previously used to decrypt the file.", new Exception()); } // get the keying material KeyParams keyParam = GetKeySet(keyStream, m_keyPackage.Description, keyPos); return(keyParam.ExtKey); } 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 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> /// 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; } }
/// <summary> /// Authentication tests; specific target domain or identity, passphrase, /// and export permissions within the PackageKey key policy settings are checked /// </summary> /// /// <returns>Authorized to use this key</returns> public KeyScope Authenticate() { try { // get the key headers m_keyPackage = GetPackage(); // store the master policy flag KeyPolicy = m_keyPackage.KeyPolicy; // did we create this key IsCreator = Compare.IsEqual(m_keyOwner.OriginId, m_keyPackage.Authority.OriginId); // key made by master auth, valid only if authenticated by PackageAuth, IdentityRestrict or DomainRestrict if (PackageKey.KeyHasPolicy(KeyPolicy, (long)KeyPolicies.MasterAuth)) { if (Compare.IsEqual(m_keyOwner.DomainId, m_keyPackage.Authority.DomainId)) { LastError = ""; return(KeyScope.Creator); } else if (Compare.IsEqual(m_keyOwner.PackageId, m_keyPackage.Authority.PackageId)) { LastError = ""; return(KeyScope.Creator); } else if (Compare.IsEqual(m_keyOwner.TargetId, m_keyPackage.Authority.TargetId)) { LastError = ""; return(KeyScope.Creator); } } // the key targets a specific installation identity if (PackageKey.KeyHasPolicy(KeyPolicy, (long)KeyPolicies.IdentityRestrict)) { // test only if not creator if (!Compare.IsEqual(m_keyOwner.OriginId, m_keyPackage.Authority.OriginId)) { // owner target field is set as a target OriginId hash if (!Compare.IsEqual(m_keyOwner.TargetId, m_keyPackage.Authority.TargetId)) { LastError = "You are not the intendant recipient of this key! Access is denied."; return(KeyScope.NoAccess); } } } if (PackageKey.KeyHasPolicy(KeyPolicy, (long)KeyPolicies.DomainRestrict)) { // the key is domain restricted if (!Compare.IsEqual(m_keyOwner.DomainId, m_keyPackage.Authority.DomainId)) { LastError = "Domain identification check has failed! You must be a member of the same Domain as the Creator of this key."; return(KeyScope.NoAccess); } } // the key package id is an authentication passphrase hash if (PackageKey.KeyHasPolicy(KeyPolicy, (long)KeyPolicies.PackageAuth)) { if (!Compare.IsEqual(m_keyOwner.PackageId, m_keyPackage.Authority.PackageId)) { LastError = "Key Package authentication has failed! Access is denied."; return(KeyScope.NoAccess); } } // test for volatile flag if (PackageKey.KeyHasPolicy(KeyPolicy, (long)KeyPolicies.Volatile)) { if (m_keyPackage.Authority.OptionFlag != 0 && m_keyPackage.Authority.OptionFlag < DateTime.Now.Ticks) { LastError = "This key has expired and can no longer be used! Access is denied."; return(KeyScope.NoAccess); } } // only the key creator is allowed access if (PackageKey.KeyHasPolicy(KeyPolicy, (long)KeyPolicies.NoExport)) { if (!Compare.IsEqual(m_keyOwner.OriginId, m_keyPackage.Authority.OriginId)) { LastError = "Only the Creator of this key is authorized! Access is denied."; return(KeyScope.NoAccess); } } LastError = ""; return(IsCreator ? KeyScope.Creator : KeyScope.Operator); } catch (Exception Ex) { LastError = Ex.Message; return(KeyScope.NoAccess); } }