/// <summary> /// Attempts to find an Inner Header and File Info object using the supplied decryption Keys. /// If the decryption keys do not decrypt the header, then they were not listed as a recipient. /// </summary> /// <param name="header">the ingested header object from the file</param> /// <param name="RecipientKeys">the Keys object with the key pair to attempt for decryption</param> /// <param name="Result">output: a FullHeader object with the fully decrypted file header details</param> /// <returns>false on any error, including (but not limited to): bad ciphertext, not a recipient</returns> private static bool TryDecryptHeader(HeaderInfo header, miniLockManaged.Keys RecipientKeys, out FullHeader Result) { Result = new FullHeader(); Result.UpdateFromHeader(header); UTF8Encoding utf8 = new UTF8Encoding(); foreach (string n in header.decryptInfo.Keys) // n is outer nonce { //System.Diagnostics.Debug.Print("decryptInfo Nonce: " + k); // DON'T LEAK!!! string v = header.decryptInfo[n]; //payload byte[] buffer = RecipientKeys.TryDecrypt(header.ephemeral, true, v.ToBytesFromBase64(), n.ToBytesFromBase64()); if (buffer != null) // looks like we're a recipient! proceed! if not just move on to the next one { string stuff = utf8.GetString(buffer); buffer.Wipe(); InnerHeaderInfo ih = InnerHeaderInfo.FromJSON(stuff); stuff = null; if (ih != null) { //System.Diagnostics.Debug.Print("_IH OBJECT=" + ih.ToJSON()); // DON'T LEAK!!! if (ih.recipientID != RecipientKeys.PublicID) { Result.Clear(); return(false); } if (!miniLockManaged.Keys.ValidatePublicKey(ih.senderID)) { Result.Clear(); return(false); } Result.UpdateFromInnerHeader(ih); buffer = ih.fileInfo.ToBytesFromBase64(); // use same nonce from OUTER buffer = RecipientKeys.TryDecrypt(ih.senderID, buffer, n.ToBytesFromBase64()); if (buffer != null) { stuff = utf8.GetString(buffer); buffer.Wipe(); FileInfo fi = FileInfo.FromJSON(stuff); if (fi != null) { Result.UpdateFromFileInfo(fi); //System.Diagnostics.Debug.Print("_FI OBJECT=" + fi.ToJSON()); // DON'T LEAK!!! return(true); } } } } } // either not a recipient, or something else went wrong Result.Clear(); return(false); }