Exemplo n.º 1
0
        /// <summary>
        ///     Determines which (if any) key is valid from a set of potential keys.
        /// </summary>
        /// <remarks>
        ///     Where appropriate, computes confirmations in parallel.
        /// </remarks>
        /// <param name="keyConfirmation">Key confirmation configuration.</param>
        /// <param name="verifiedOutput">Known/verified output of the function if correct key is input.</param>
        /// <param name="potentialKeys">Set of potential keys used by the sender.</param>
        /// <exception cref="ArgumentNullException">Key confirmation configuration, verified output, or potential keys is null.</exception>
        /// <exception cref="ConfigurationInvalidException">
        ///     Some aspect of configuration invalid - detailed inside exception message.
        /// </exception>
        /// <returns>Valid key, or null if none are validated as being correct.</returns>
        public static SymmetricKey ConfirmKeyFromCanary(AuthenticationConfiguration keyConfirmation,
                                                        byte[] verifiedOutput, IEnumerable <SymmetricKey> potentialKeys)
        {
            if (keyConfirmation == null)
            {
                throw new ArgumentNullException("keyConfirmation", "No configuration supplied.");
            }
            if (potentialKeys == null)
            {
                throw new ArgumentNullException("potentialKeys", "No potential keys supplied.");
            }

            Func <byte[], byte[]> validator = GetValidator(keyConfirmation, TagConstantBytes,
                                                           keyConfirmation.SerialiseDto(), verifiedOutput.Length);

            SymmetricKey preKey = null;

            Parallel.ForEach(potentialKeys, (key, state) =>
            {
                byte[] validationOut = validator(key.ConfirmationCanary);
                if (validationOut.SequenceEqual_ConstantTime(verifiedOutput))
                {
                    preKey = key;
                    // Terminate all other validation function instances - we have found the key
                    state.Stop();
                }
            });

            return(preKey);
        }
Exemplo n.º 2
0
        /// <summary>
        ///     Generate a verified output of a function given the correct key, to be used as a key confirmation.
        ///     Uses confirmation canary.
        /// </summary>
        /// <param name="configuration">Configuration of the verification function.</param>
        /// <param name="senderKeypair">Sender keypair to generate a confirmation output verification for.</param>
        /// <param name="recipientKey">Recipient key to generate a confirmation output verification for.</param>
        /// <returns>Output of the verification function, given the correct key.</returns>
        /// <exception cref="ArgumentException">Key is null or zero-length.</exception>
        /// <seealso cref="SymmetricKey"/>
        /// <seealso cref="ECKeypair"/>
        /// <seealso cref="IPossessConfirmationCanary"/>
        public static byte[] GenerateVerifiedOutput(AuthenticationConfiguration configuration, ECKeypair senderKeypair, ECKey recipientKey)
        {
            Func <byte[], byte[]> validator = GetValidator(configuration, TagConstantBytes,
                                                           configuration.SerialiseDto());

            byte[] canary         = XorCanaryBytes(senderKeypair.ConfirmationCanary, recipientKey.ConfirmationCanary);
            byte[] verifiedOutput = validator(canary);

            Debug.Print(DebugUtility.CreateReportString("ConfirmationUtility", "GenerateVerifiedOutput",
                                                        "Verified output",
                                                        verifiedOutput.ToHexString()));

            return(verifiedOutput);
        }
Exemplo n.º 3
0
        /// <summary>
        ///     Generate a verified output of a function given the correct canary, to be used as a key confirmation.
        /// </summary>
        /// <param name="configuration">Configuration of the verification function.</param>
        /// <param name="canary">Confirmation canary to generate a confirmation output verification for.</param>
        /// <returns>Output of the verification function, given the correct canary.</returns>
        /// <exception cref="ArgumentException">Key is null or zero-length.</exception>
        /// <seealso cref="SymmetricKey"/>
        /// <seealso cref="ECKeypair"/>
        /// <seealso cref="IPossessConfirmationCanary"/>
        public static byte[] GenerateVerifiedOutput(AuthenticationConfiguration configuration, byte[] canary)
        {
            if (canary.IsNullOrZeroLength())
            {
                throw new ArgumentException("Canary is null or zero-length.", "canary");
            }

            Func <byte[], byte[]> validator = GetValidator(configuration, TagConstantBytes,
                                                           configuration.SerialiseDto());

            byte[] verifiedOutput = validator(canary);

            Debug.Print(DebugUtility.CreateReportString("ConfirmationUtility", "GenerateVerifiedOutput",
                                                        "Verified output",
                                                        verifiedOutput.ToHexString()));

            return(verifiedOutput);
        }
Exemplo n.º 4
0
        /// <summary>
        ///     Determines which (if any) key is valid from a set of potential keys.
        /// </summary>
        /// <remarks>
        ///     Where appropriate, computes confirmations in parallel.
        /// </remarks>
        /// <param name="keyConfirmation">Key confirmation configuration.</param>
        /// <param name="verifiedOutput">Known/verified output of the function if correct key is input.</param>
        /// <param name="potentialSenderKeys">Set of potential public keys used by the sender.</param>
        /// <param name="ephemeralKey"></param>
        /// <param name="potentialRecipientKeys">Keys used by the recipient that the sender may have used.</param>
        /// <param name="senderKey">Output of the public key associated with the private key used by the sender.</param>
        /// <param name="recipientKeypair">Output of the keypair that contains the public key used by the sender.</param>
        /// <exception cref="ArgumentNullException">Some input argument is null.</exception>
        /// <exception cref="ConfigurationInvalidException">
        ///     Some aspect of configuration invalid - detailed inside exception message.
        /// </exception>
        /// <returns>Valid key, or null if none are validated as being correct.</returns>
        public static void ConfirmKeyFromCanary(AuthenticationConfiguration keyConfirmation,
                                                byte[] verifiedOutput, IEnumerable <ECKey> potentialSenderKeys, ECKey ephemeralKey,
                                                IEnumerable <ECKeypair> potentialRecipientKeys, out ECKey senderKey, out ECKeypair recipientKeypair)
        {
            if (keyConfirmation == null)
            {
                throw new ArgumentNullException("keyConfirmation", "No configuration supplied.");
            }
            if (ephemeralKey == null)
            {
                throw new ArgumentNullException("ephemeralKey", "No ephemeral key supplied.");
            }
            if (potentialSenderKeys == null)
            {
                throw new ArgumentNullException("potentialSenderKeys", "No potential sender keys supplied.");
            }
            if (ephemeralKey == null)
            {
                throw new ArgumentNullException("ephemeralKey", "No ephemeral key supplied.");
            }
            if (potentialRecipientKeys == null)
            {
                throw new ArgumentNullException("potentialRecipientKeys", "No potential recipient keys supplied.");
            }

            // We can determine which, if any, of the provided keys are capable of decrypting the manifest
            var viableSenderKeys = potentialSenderKeys.AsQueryExpr().Where(key =>
                                                                           key.CurveProviderName.Equals(ephemeralKey.CurveProviderName) &&
                                                                           key.CurveName.Equals(ephemeralKey.CurveName)).Run().ToArray();

            if (viableSenderKeys.Length == 0)
            {
                throw new ArgumentException(
                          "No viable sender keys found - curve provider and/or curve name do not match ephemeral key.",
                          "potentialSenderKeys");
            }

            var viableRecipientKeypairs = potentialRecipientKeys.AsQueryExpr().Where(key =>
                                                                                     key.CurveProviderName.Equals(ephemeralKey.CurveProviderName) &&
                                                                                     key.CurveName.Equals(ephemeralKey.CurveName)).Run().ToArray();

            if (viableRecipientKeypairs.Length == 0)
            {
                throw new ArgumentException(
                          "No viable recipient keys found - curve provider and/or curve name do not match ephemeral key.",
                          "potentialRecipientKeys");
            }

            Func <byte[], byte[]> validator = GetValidator(keyConfirmation, TagConstantBytes,
                                                           keyConfirmation.SerialiseDto(), verifiedOutput.Length);

            // Temporary variables to store output in (can't access 'out' parameters inside anonymous method body)
            ECKey     oSK  = null;
            ECKeypair oRKP = null;

            // See which mode (by-sender / by-recipient) is better to run in parallel
            if (viableRecipientKeypairs.Length > viableSenderKeys.Length)
            {
                Parallel.ForEach(viableRecipientKeypairs, (rKeypair, state) => {
                    foreach (ECKey sKey in viableSenderKeys)
                    {
                        byte[] canary        = XorCanaryBytes(sKey.ConfirmationCanary, rKeypair.ConfirmationCanary);
                        byte[] validationOut = validator(canary);
                        if (validationOut.SequenceEqual_ConstantTime(verifiedOutput))
                        {
                            oSK  = sKey;
                            oRKP = rKeypair;
                            state.Stop();
                        }
                    }
                });
            }
            else
            {
                Parallel.ForEach(viableSenderKeys, (sKey, state) => {
                    foreach (var rKeypair in viableRecipientKeypairs)
                    {
                        byte[] canary        = XorCanaryBytes(sKey.ConfirmationCanary, rKeypair.ConfirmationCanary);
                        byte[] validationOut = validator(canary);
                        if (validationOut.SequenceEqual_ConstantTime(verifiedOutput))
                        {
                            oSK  = sKey;
                            oRKP = rKeypair;
                            state.Stop();
                        }
                    }
                });
            }

            // Assign the outputs to the 'out' parameters
            senderKey        = oSK;
            recipientKeypair = oRKP;
        }