Example #1
0
        /// <summary>
        ///     Validate a file with a MinisignSignature and a MinisignPublicKey object.
        /// </summary>
        /// <param name="message">The message to validate.</param>
        /// <param name="signature">A valid MinisignSignature object.</param>
        /// <param name="publicKey">A valid MinisignPublicKey object.</param>
        /// <returns><c>true</c> if valid; otherwise, <c>false</c>.</returns>
        /// <exception cref="OverflowException"></exception>
        /// <exception cref="ArgumentNullException"></exception>
        /// <exception cref="ArgumentException"></exception>
        /// <exception cref="ArgumentOutOfRangeException"></exception>
        public static bool ValidateSignature(byte[] message, MinisignSignature signature, MinisignPublicKey publicKey)
        {
            if (message == null)
                throw new ArgumentException("missing signature input", "message");

            if (signature == null)
                throw new ArgumentException("missing signature input", "signature");

            if (publicKey == null)
                throw new ArgumentException("missing publicKey input", "publicKey");

            if (!ArrayHelpers.ConstantTimeEquals(signature.KeyId, publicKey.KeyId)) return false;
            // verify the signature
            if (PublicKeyAuth.VerifyDetached(signature.Signature, message, publicKey.PublicKey))
            {
                // verify the trusted comment
                return PublicKeyAuth.VerifyDetached(signature.GlobalSignature,
                    ArrayHelpers.ConcatArrays(signature.Signature, signature.TrustedComment), publicKey.PublicKey);
            }

            return false;
        }
Example #2
0
        /// <summary>
        ///     Sign a file with a MinisignPrivateKey.
        /// </summary>
        /// <param name="fileToSign">The full path to the file.</param>
        /// <param name="minisignPrivateKey">A valid MinisignPrivateKey to sign.</param>
        /// <param name="untrustedComment">An optional untrusted comment.</param>
        /// <param name="trustedComment">An optional trusted comment.</param>
        /// <param name="outputFolder">The folder to write the signature (optional).</param>
        /// <returns>The full path to the signed file.</returns>
        /// <exception cref="FileNotFoundException"></exception>
        /// <exception cref="ArgumentException"></exception>
        /// <exception cref="ArgumentOutOfRangeException"></exception>
        /// <exception cref="OverflowException"></exception>
        /// <exception cref="DirectoryNotFoundException"></exception>
        /// <exception cref="IOException"></exception>
        /// <exception cref="UnauthorizedAccessException"></exception>
        /// <exception cref="SecurityException"></exception>
        /// <exception cref="ArgumentNullException"></exception>
        /// <exception cref="PathTooLongException"></exception>
        /// <exception cref="NotSupportedException"></exception>
        public static string Sign(string fileToSign, MinisignPrivateKey minisignPrivateKey, string untrustedComment = "",
			string trustedComment = "", string outputFolder = "")
        {
            if (fileToSign != null && !File.Exists(fileToSign))
            {
                throw new FileNotFoundException("could not find fileToSign");
            }

            if (minisignPrivateKey == null)
                throw new ArgumentException("missing minisignPrivateKey input", "minisignPrivateKey");

            if (string.IsNullOrEmpty(untrustedComment))
            {
                untrustedComment = DefaultComment;
            }

            if (string.IsNullOrEmpty(trustedComment))
            {
                var timestamp = GetTimestamp();
                var filename = Path.GetFileName(fileToSign);
                trustedComment = "timestamp: " + timestamp + " file: " + filename;
            }

            if ((CommentPrefix + untrustedComment).Length > CommentMaxBytes)
            {
                throw new ArgumentOutOfRangeException("untrustedComment", "untrustedComment too long");
            }

            if ((TrustedCommentPrefix + trustedComment).Length > TrustedCommentMaxBytes)
            {
                throw new ArgumentOutOfRangeException("trustedComment", "trustedComment too long");
            }

            if (string.IsNullOrEmpty(outputFolder))
            {
                outputFolder = Path.GetDirectoryName(fileToSign);
            }

            //validate the outputFolder
            if (string.IsNullOrEmpty(outputFolder) || !Directory.Exists(outputFolder))
            {
                throw new DirectoryNotFoundException("outputFolder must exist");
            }

            if (outputFolder.IndexOfAny(Path.GetInvalidPathChars()) > -1)
                throw new ArgumentException("The given path to the output folder contains invalid characters!");

            var file = LoadMessageFile(fileToSign);

            var minisignSignature = new MinisignSignature();
            minisignSignature.KeyId = minisignPrivateKey.KeyId;
            minisignSignature.SignatureAlgorithm = Encoding.UTF8.GetBytes(Sigalg);
            var signature = PublicKeyAuth.SignDetached(file, minisignPrivateKey.SecretKey);
            minisignSignature.Signature = signature;

            var binarySignature = ArrayHelpers.ConcatArrays(
                minisignSignature.SignatureAlgorithm,
                minisignSignature.KeyId,
                minisignSignature.Signature
                );

            // sign the signature and the trusted comment with a global signature
            var globalSignature =
                PublicKeyAuth.SignDetached(
                    ArrayHelpers.ConcatArrays(minisignSignature.Signature, Encoding.UTF8.GetBytes(trustedComment)),
                    minisignPrivateKey.SecretKey);

            // prepare the file lines
            var signatureFileContent = new[]
            {
                CommentPrefix + untrustedComment,
                Convert.ToBase64String(binarySignature),
                TrustedCommentPrefix + trustedComment,
                Convert.ToBase64String(globalSignature)
            };

            var outputFile = fileToSign + SigSuffix;
            File.WriteAllLines(outputFile, signatureFileContent);
            return outputFile;
        }
Example #3
0
        /// <summary>
        ///     Validate a file with a MinisignSignature and a MinisignPublicKey object.
        /// </summary>
        /// <param name="filePath">The full path to the file.</param>
        /// <param name="signature">A valid MinisignSignature object.</param>
        /// <param name="publicKey">A valid MinisignPublicKey object.</param>
        /// <returns><c>true</c> if valid; otherwise, <c>false</c>.</returns>
        /// <exception cref="FileNotFoundException"></exception>
        /// <exception cref="OverflowException"></exception>
        /// <exception cref="ArgumentNullException"></exception>
        /// <exception cref="ArgumentException"></exception>
        /// <exception cref="ArgumentOutOfRangeException"></exception>
        public static bool ValidateSignature(string filePath, MinisignSignature signature, MinisignPublicKey publicKey)
        {
            if (filePath != null && !File.Exists(filePath))
            {
                throw new FileNotFoundException("could not find filePath");
            }

            if (signature == null)
                throw new ArgumentException("missing signature input", "signature");

            if (publicKey == null)
                throw new ArgumentException("missing publicKey input", "publicKey");

            if (!ArrayHelpers.ConstantTimeEquals(signature.KeyId, publicKey.KeyId)) return false;
            // load the file into memory
            var file = LoadMessageFile(filePath);
            // verify the signature
            if (PublicKeyAuth.VerifyDetached(signature.Signature, file, publicKey.PublicKey))
            {
                // verify the trusted comment
                return PublicKeyAuth.VerifyDetached(signature.GlobalSignature,
                    ArrayHelpers.ConcatArrays(signature.Signature, signature.TrustedComment), publicKey.PublicKey);
            }

            return false;
        }
Example #4
0
        /// <summary>
        ///     Load a signature into a MinisignSignature object.
        /// </summary>
        /// <param name="signature">A valid signature.</param>
        /// <param name="trustedComment">The associated trustedComment.</param>
        /// <param name="globalSignature">The associated globalSignature.</param>
        /// <returns>A MinisignSignature object.</returns>
        /// <exception cref="OverflowException"></exception>
        /// <exception cref="ArgumentNullException"></exception>
        /// <exception cref="ArgumentException"></exception>
        /// <exception cref="ArgumentOutOfRangeException"></exception>
        public static MinisignSignature LoadSignature(byte[] signature, byte[] trustedComment, byte[] globalSignature)
        {
            if (signature == null)
                throw new ArgumentException("missing signature input", "signature");

            if (trustedComment == null)
                throw new ArgumentException("missing trustedComment input", "trustedComment");

            if (globalSignature == null)
                throw new ArgumentException("missing globalSignature input", "globalSignature");

            var minisignSignature = new MinisignSignature
            {
                SignatureAlgorithm = ArrayHelpers.SubArray(signature, 0, 2),
                KeyId = ArrayHelpers.SubArray(signature, 2, 8),
                Signature = ArrayHelpers.SubArray(signature, 10),
                TrustedComment = trustedComment,
                GlobalSignature = globalSignature
            };
            return minisignSignature;
        }