Exemplo n.º 1
0
        public void SignFile(string inputFileName, X509Certificate2 certificate, string timestampServer,
                             SignFileRequest signFileRequest, SignFileResponse signFileResponse)
        {
            var successResult = SignFileResponseResult.FileSigned;

            if (IsFileSigned(inputFileName))
            {
                if (signFileRequest.OverwriteSignature)
                {
                    UnsignFile(inputFileName);
                    successResult = SignFileResponseResult.FileResigned;
                }
                else
                {
                    signFileResponse.Result = SignFileResponseResult.FileAlreadySigned;
                    return;
                }
            }


            SignatureHelper.SignFile(SigningOption.Default, inputFileName, certificate, timestampServer, signFileRequest.HashAlgorithm);

            signFileResponse.Result      = successResult;
            signFileResponse.FileContent = new FileStream(inputFileName, FileMode.Open, FileAccess.Read);
            signFileResponse.FileSize    = signFileResponse.FileContent.Length;
        }
Exemplo n.º 2
0
        protected void CannotResign(ISigningTool signingTool, string fileName, string pfx)
        {
            var certificate = new X509Certificate2(pfx);

            Assert.IsTrue(signingTool.IsFileSupported(fileName));

            var response = new SignFileResponse();
            var request  = new SignFileRequest
            {
                FileName           = fileName,
                OverwriteSignature = false
            };

            signingTool.SignFile(fileName, certificate, ConfigurationManager.AppSettings["TimestampServer"], request, response);

            Trace.WriteLine(response);
            try
            {
                Assert.AreEqual(SignFileResponseResult.FileAlreadySigned, response.Result);
                Assert.IsTrue(signingTool.IsFileSigned(fileName));
                Assert.AreEqual(0, response.FileSize);
            }
            finally
            {
                response.Dispose();
            }
        }
Exemplo n.º 3
0
        protected void CanResign(ISigningTool signingTool, string fileName, string pfx)
        {
            var certificate = new X509Certificate2(pfx);

            Assert.IsTrue(signingTool.IsFileSupported(fileName));

            var response = new SignFileResponse();
            var request  = new SignFileRequest
            {
                FileName           = fileName,
                OverwriteSignature = true
            };

            signingTool.SignFile(fileName, certificate, ConfigurationManager.AppSettings["TimestampServer"], request, response);

            try
            {
                Assert.AreEqual(SignFileResponseResult.FileResigned, response.Result);
                Assert.IsTrue(signingTool.IsFileSigned(fileName));
                Assert.IsNotNull(response.FileContent);
                Assert.IsTrue(response.FileSize > 0);
                using (var data = new MemoryStream())
                {
                    using (response.FileContent)
                    {
                        response.FileContent.CopyTo(data);
                        Assert.AreEqual(response.FileSize, data.ToArray().Length);
                    }
                }
            }
            finally
            {
                response.Dispose();
            }
        }
        public void SignFile(string inputFileName, X509Certificate2 certificate, string timestampServer,
                             SignFileRequest signFileRequest, SignFileResponse signFileResponse)
        {
            SignFileResponseResult successResult = SignFileResponseResult.FileSigned;

            if (IsFileSigned(inputFileName))
            {
                if (signFileRequest.OverwriteSignature)
                {
                    UnsignFile(inputFileName);
                    successResult = SignFileResponseResult.FileResigned;
                }
                else
                {
                    signFileResponse.Result = SignFileResponseResult.FileAlreadySigned;
                    return;
                }
            }

            SecurityUtilities.SignFile(certificate, new Uri(timestampServer), inputFileName);

            signFileResponse.Result      = successResult;
            signFileResponse.FileContent = new FileStream(inputFileName, FileMode.Open, FileAccess.Read);
            signFileResponse.FileSize    = signFileResponse.FileContent.Length;
        }
Exemplo n.º 5
0
        public void SignFile(string inputFileName, X509Certificate2 certificate, string timestampServer,
                             SignFileRequest signFileRequest, SignFileResponse signFileResponse)
        {
            SignFileResponseResult successResult = SignFileResponseResult.FileSigned;

            if (IsFileSigned(inputFileName))
            {
                if (signFileRequest.OverwriteSignature)
                {
                    successResult = SignFileResponseResult.FileResigned;
                }
                else
                {
                    signFileResponse.Result = SignFileResponseResult.FileAlreadySigned;
                    return;
                }
            }

            var outputFileName = inputFileName + ".signed";

            try
            {
                if (string.IsNullOrEmpty(signFileRequest.HashAlgorithm) || !ApkSupportedHashAlgorithms.TryGetValue(signFileRequest.HashAlgorithm, out var digestAlgorithm))
                {
                    digestAlgorithm = null;
                }

                var isV2SigningEnabled =
                    ".apk".Equals(Path.GetExtension(inputFileName), StringComparison.InvariantCultureIgnoreCase) && // v2 only for APKs not for JARs
                    (digestAlgorithm == null || !digestAlgorithm.Equals(DigestAlgorithm.SHA1))                      // v2 signing requires SHA256 or SHA512
                ;

                var apkSigner = new ApkSigner(certificate, inputFileName, outputFileName)
                {
                    V1SigningEnabled = true,
                    V2SigningEnabled = isV2SigningEnabled,
                    DigestAlgorithm  = digestAlgorithm
                };

                apkSigner.Sign();

                File.Delete(inputFileName);
                File.Move(outputFileName, inputFileName);

                signFileResponse.Result      = successResult;
                signFileResponse.FileContent = new FileStream(inputFileName, FileMode.Open, FileAccess.Read);
                signFileResponse.FileSize    = signFileResponse.FileContent.Length;
            }
            catch
            {
                if (File.Exists(outputFileName))
                {
                    File.Delete(outputFileName);
                }
                throw;
            }
        }
        public void SignFile_Unsigned_WrongPublishedFails()
        {
            using (var signingTool = new AppxSigningTool(Log))
            {
                var fileName    = "Unsigned_WrongPublishedFails/error/UnsignedWrongPublisher.appx";
                var certificate = new X509Certificate2("Certificates/SigningServer.Test.pfx");
                Assert.IsTrue(signingTool.IsFileSupported(fileName));

                var response = new SignFileResponse();
                var request  = new SignFileRequest
                {
                    FileName           = fileName,
                    OverwriteSignature = true
                };
                signingTool.SignFile(fileName, certificate, ConfigurationManager.AppSettings["TimestampServer"], request, response);

                Trace.WriteLine(response);
                Assert.AreEqual(SignFileResponseResult.FileNotSignedError, response.Result);
                Assert.IsFalse(signingTool.IsFileSigned(fileName));
                Assert.IsInstanceOfType(response.FileContent, typeof(MemoryStream));
                Assert.AreEqual(response.FileSize, response.FileContent.Length);
                Assert.AreEqual(0, response.FileSize);
            }
        }
Exemplo n.º 7
0
        public void SignFile(string inputFileName, X509Certificate2 certificate, string timestampServer,
                             SignFileRequest signFileRequest, SignFileResponse signFileResponse)
        {
            SignFileResponseResult successResult = SignFileResponseResult.FileSigned;

            if (IsFileSigned(inputFileName))
            {
                if (signFileRequest.OverwriteSignature)
                {
                    UnsignFile(inputFileName);
                    successResult = SignFileResponseResult.FileResigned;
                }
                else
                {
                    signFileResponse.Result      = SignFileResponseResult.FileAlreadySigned;
                    signFileResponse.FileContent = null;
                    return;
                }
            }

            var outputFileName = inputFileName + ".signed";

            try
            {
                HashAlgorithmInfo hashAlgorithmInfo;
                if (!ApkSupportedHashAlgorithms.TryGetValue(signFileRequest.HashAlgorithm ?? DefaultHashAlgorithm, out hashAlgorithmInfo))
                {
                    hashAlgorithmInfo = ApkSupportedHashAlgorithms[DefaultHashAlgorithm];
                }

                using (var inputJar = new ZipFile(inputFileName))
                {
                    using (var outputJar = ZipFile.Create(outputFileName))
                    {
                        outputJar.BeginUpdate();

                        var manifest = CreateSignedManifest(inputJar, outputJar, hashAlgorithmInfo);

                        var signatureFile = CreateSignatureFile(outputJar, manifest, hashAlgorithmInfo);

                        CreateSignatureBlockFile(outputJar, certificate, signatureFile, timestampServer);

                        outputJar.CommitUpdate();
                        outputJar.BeginUpdate();

                        foreach (var entry in inputJar.OfType <ZipEntry>())
                        {
                            if (entry.IsDirectory)
                            {
                                outputJar.AddDirectory(entry.Name);
                            }
                            else if (outputJar.FindEntry(entry.Name, true) == -1)
                            {
                                Log.Trace($"Cloning file ${entry.Name} into new zip");
                                outputJar.Add(new ZipEntryDataSource(inputJar, entry), entry.Name);
                            }
                        }

                        outputJar.CommitUpdate();
                        outputJar.Close();
                    }
                }

                File.Delete(inputFileName);
                File.Move(outputFileName, inputFileName);

                signFileResponse.Result      = successResult;
                signFileResponse.FileContent = new FileStream(inputFileName, FileMode.Open, FileAccess.Read);
                signFileResponse.FileSize    = signFileResponse.FileContent.Length;
            }
            catch
            {
                if (File.Exists(outputFileName))
                {
                    File.Delete(outputFileName);
                }
                throw;
            }
        }
        public SignFileResponse SignFile(SignFileRequest signFileRequest)
        {
            var signFileResponse = new SignFileResponse();

            signFileResponse.DeleteFailed += (response, file, exception) =>
            {
                Log.Error(exception, $"Failed to delete file '{file}'");
            };
            signFileResponse.DeleteSkipped += (response, file) =>
            {
                Log.Warn($"Skipped file delete '{file}'");
            };
            signFileResponse.DeleteSuccess += (response, file) =>
            {
                Log.Trace($"Successfully deleted file '{file}'");
            };

            var    remoteIp      = RemoteIp;
            var    isLegacy      = IsLegacyEndpoint;
            string inputFileName = null;

            try
            {
                //
                // validate input
                if (isLegacy)
                {
                    Log.Warn($"[{remoteIp}] Client is using legacy endpoint!");
                }

                Log.Info($"[{remoteIp}] New sign request for file {signFileRequest.FileName} by {remoteIp} ({signFileRequest.FileSize} bytes)");
                if (signFileRequest.FileSize == 0 || signFileRequest.FileContent == null)
                {
                    signFileResponse.Result       = SignFileResponseResult.FileNotSignedError;
                    signFileResponse.ErrorMessage = "No file was received";
                    return(signFileResponse);
                }

                //
                // find certificate
                CertificateConfiguration certificate;
                if (string.IsNullOrWhiteSpace(signFileRequest.Username))
                {
                    certificate = Configuration.Certificates.FirstOrDefault(c => c.IsAnonymous);
                }
                else
                {
                    certificate = Configuration.Certificates.FirstOrDefault(
                        c => c.IsAuthorized(signFileRequest.Username, signFileRequest.Password));
                }
                if (certificate == null)
                {
                    Log.Warn("Unauthorized signing request");
                    signFileResponse.Result = SignFileResponseResult.FileNotSignedUnauthorized;
                    return(signFileResponse);
                }

                //
                // find compatible signing tool
                var signingTool = SigningToolProvider.GetSigningTool(signFileRequest.FileName);
                if (signingTool == null)
                {
                    signFileResponse.Result = SignFileResponseResult.FileNotSignedUnsupportedFormat;
                    return(signFileResponse);
                }

                //
                // upload file to working directory
                inputFileName = signFileRequest.FileName ?? "";
                inputFileName = DateTime.Now.ToString("yyyyMMdd_HHmmss") + "_" + Path.GetFileNameWithoutExtension(inputFileName) + "_" + Guid.NewGuid() + (Path.GetExtension(inputFileName));
                inputFileName = Path.Combine(Configuration.WorkingDirectory, inputFileName);
                using (var targetFile = new FileStream(inputFileName, FileMode.Create, FileAccess.ReadWrite))
                {
                    signFileRequest.FileContent.CopyTo(targetFile);
                }

                //
                // sign file
                signingTool.SignFile(inputFileName, certificate.Certificate, Configuration.TimestampServer, signFileRequest, signFileResponse);

                Log.Info($"[{remoteIp}] New sign request for file {signFileRequest.FileName} finished ({signFileRequest.FileSize} bytes)");

                switch (signFileResponse.Result)
                {
                case SignFileResponseResult.FileSigned:
                case SignFileResponseResult.FileResigned:
                    break;

                case SignFileResponseResult.FileAlreadySigned:
                case SignFileResponseResult.FileNotSignedUnsupportedFormat:
                case SignFileResponseResult.FileNotSignedError:
                case SignFileResponseResult.FileNotSignedUnauthorized:
                    // ensure input file is cleaned in error cases where the sign tool does not have a result
                    if (!(signFileResponse.FileContent is FileStream))
                    {
                        try
                        {
                            Log.Trace($"Deleting file {inputFileName}");
                            File.Delete(inputFileName);
                            Log.Trace($"File successfully deleted {inputFileName}");
                        }
                        catch (Exception e)
                        {
                            Log.Error(e, "Could not delete input file for failed request");
                        }
                    }
                    else
                    {
                        Log.Trace($"Delete file skipped for failed request {signFileResponse.Result} {inputFileName}, {signFileResponse.FileContent.GetType()}");
                    }
                    break;
                }
            }
            catch (Exception e)
            {
                Log.Error(e, $"[{remoteIp}] Signing of {signFileRequest.FileName} failed: {e.Message}");
                signFileResponse.Result       = SignFileResponseResult.FileNotSignedError;
                signFileResponse.ErrorMessage = e.Message;
                if (!string.IsNullOrEmpty(inputFileName) && File.Exists(inputFileName))
                {
                    try
                    {
                        File.Delete(inputFileName);
                    }
                    catch (Exception fileException)
                    {
                        Log.Error(fileException, $"[{remoteIp}] Failed to delete file {inputFileName}");
                    }
                }
            }

            return(signFileResponse);
        }
Exemplo n.º 9
0
        public SignFileResponse SignFile(SignFileRequest signFileRequest)
        {
            var    signFileResponse = new SignFileResponse();
            var    remoteIp         = RemoteIp;
            string inputFileName    = null;

            try
            {
                //
                // validate input
                Log.Info("New sign request for file {0} by {1} ({2} bytes)", signFileRequest.FileName, remoteIp, signFileRequest.FileSize);
                if (signFileRequest.FileSize == 0 || signFileRequest.FileContent == null)
                {
                    signFileResponse.Result       = SignFileResponseResult.FileNotSignedError;
                    signFileResponse.ErrorMessage = "No file was received";
                    return(signFileResponse);
                }

                //
                // find certificate
                CertificateConfiguration certificate;
                if (string.IsNullOrWhiteSpace(signFileRequest.Username))
                {
                    certificate = Configuration.Certificates.FirstOrDefault(c => c.IsAnonymous);
                }
                else
                {
                    certificate = Configuration.Certificates.FirstOrDefault(
                        c => c.IsAuthorized(signFileRequest.Username, signFileRequest.Password));
                }
                if (certificate == null)
                {
                    Log.Warn("Unauthorized signing request");
                    signFileResponse.Result = SignFileResponseResult.FileNotSignedUnauthorized;
                    return(signFileResponse);
                }

                //
                // find compatible signing tool
                var signingTool = SigningToolProvider.GetSigningTool(signFileRequest.FileName);
                if (signingTool == null)
                {
                    signFileResponse.Result = SignFileResponseResult.FileNotSignedUnsupportedFormat;
                    return(signFileResponse);
                }

                //
                // upload file to working directory
                inputFileName = signFileRequest.FileName ?? "";
                inputFileName = DateTime.Now.ToString("yyyyMMdd_HHmmss") + "_" + Path.GetFileNameWithoutExtension(inputFileName) + "_" + Guid.NewGuid() + (Path.GetExtension(inputFileName));
                inputFileName = Path.Combine(Configuration.WorkingDirectory, inputFileName);
                using (var targetFile = new FileStream(inputFileName, FileMode.Create, FileAccess.ReadWrite))
                {
                    signFileRequest.FileContent.CopyTo(targetFile);
                }

                //
                // sign file
                signingTool.SignFile(inputFileName, certificate.Certificate, Configuration.TimestampServer, signFileRequest, signFileResponse);

                Log.Info("New sign request for file {0} finished ({1} bytes)", signFileRequest.FileName, signFileRequest.FileSize);
            }
            catch (Exception e)
            {
                Log.Error(e, $"Signing of {signFileRequest.FileName} by {remoteIp} failed: {e.Message}");
                signFileResponse.Result       = SignFileResponseResult.FileNotSignedError;
                signFileResponse.ErrorMessage = e.Message;
                if (!string.IsNullOrEmpty(inputFileName) && File.Exists(inputFileName))
                {
                    try
                    {
                        File.Delete(inputFileName);
                    }
                    catch (Exception fileException)
                    {
                        Log.Error(fileException, $"Failed to delete file {inputFileName} by {remoteIp}");
                    }
                }
            }

            return(signFileResponse);
        }