示例#1
0
 /// <summary>
 /// Конструктор для создания копии контейнера
 /// </summary>
 /// <param name="c"></param>
 public CertInfo(CertInfo c)
 {
     this._OwnerC       = c.OwnerC;
     this._FullInfo     = c.FullInfo;
     this._OwnerCN      = c.OwnerCN;
     this._OwnerEmail   = c.OwnerEmail;
     this._OwnerL       = c.OwnerL;
     this._OwnerO       = c.OwnerO;
     this._OwnerOU      = c.OwnerOU;
     this._OwnerST      = c.OwnerST;
     this._pemPath      = c.pemPath;
     this._pk8Path      = c.pk8Path;
     this._SerialNumber = c.SerialNumber;
 }
示例#2
0
 /// <summary>
 /// Конструктор для создания копии контейнера
 /// </summary>
 /// <param name="c"></param>
 public CertInfo(CertInfo c)
 {
     this._OwnerC = c.OwnerC;
     this._FullInfo = c.FullInfo;
     this._OwnerCN = c.OwnerCN;
     this._OwnerEmail = c.OwnerEmail;
     this._OwnerL = c.OwnerL;
     this._OwnerO = c.OwnerO;
     this._OwnerOU = c.OwnerOU;
     this._OwnerST = c.OwnerST;
     this._pemPath = c.pemPath;
     this._pk8Path = c.pk8Path;
     this._SerialNumber = c.SerialNumber;
 }
示例#3
0
        /// <summary>
        /// Считывает информацию о текущей подписи из ZIP-архива
        /// </summary>
        /// <param name="fPath">Путь до файла (*.zip, *.apk, *.jar)</param>
        /// <returns></returns>
        public static CertInfo ReadZip(string fPath)
        {
            string     cFile = Path.Combine(Environment.TempPath, Path.GetFileName(fPath) + "_CERT.RSA");
            ZipFile    zf    = null;
            FileStream fs    = null;

            try
            {
                fs = File.OpenRead(fPath);
                zf = new ZipFile(fs);
            }
            catch { return(null); }

            //ищем файл подписи
            bool IsExtracted = false;

            foreach (ZipEntry zipEntry in zf)
            {
                if (!zipEntry.IsFile)
                {
                    continue;
                }
                if (zipEntry.Name == "META-INF/CERT.RSA")
                {
                    Environment.Log(string.Format("Найден файл подписи, извлекаем его в \"{0}\"...", cFile));
                    //Если нашли, извлекаем его во временную директорию
                    byte[] buffer    = new byte[4096];
                    Stream zipStream = zf.GetInputStream(zipEntry);
                    using (FileStream streamWriter = File.Create(cFile))
                        StreamUtils.Copy(zipStream, streamWriter, buffer);
                    IsExtracted = true;
                }
            }

            if (!IsExtracted)
            {
                Environment.Log("Файл подписи не найден");
                return(null);
            }

            CertInfo cInfo = ReadCert(cFile, false);

            try { File.Delete(cFile); }
            catch (Exception ex) { Environment.Log(string.Format("Не удалось удалить временный файл \"{0}\". Ошибка: {1}", cFile, ex.Message)); }

            return(cInfo);
        }
示例#4
0
        /// <summary>
        /// Парсинг информации о подписи из keytool
        /// </summary>
        /// <param name="Data">Выходные данные утилиты keytool</param>
        /// <returns>Структура с информацией о подписи</returns>
        public static CertInfo Parse(string Data)
        {
            //Извлекаем серийный номер
            string sNum = null;
            foreach (string line in Data.Split('\n'))
                if (line.Contains(keyToolLine))
                {
                    sNum = line.Replace(keyToolLine, string.Empty);
                    break;
                }

            if (sNum == null)
                return null;

            //Если не нашли, создаем новый и добавляем его в коллекцию
            CertInfo cInfo = new CertInfo() { SerialNumber = sNum, FullInfo = Data };

            //Извлекаем инфу о владельце
            Regex rx_EMAIL = new Regex("(EMAILADDRESS=)(.*?)(,|$)", RegexOptions.IgnoreCase | RegexOptions.Singleline);
            Regex rx_CN = new Regex("(CN=)(.*?)(,|$)", RegexOptions.IgnoreCase | RegexOptions.Singleline);
            Regex rx_OU = new Regex("(OU=)(.*?)(,|$)", RegexOptions.IgnoreCase | RegexOptions.Singleline);
            Regex rx_O = new Regex("(O=)(.*?)(,|$)", RegexOptions.IgnoreCase | RegexOptions.Singleline);
            Regex rx_L = new Regex("(L=)(.*?)(,|$)", RegexOptions.IgnoreCase | RegexOptions.Singleline);
            Regex rx_ST = new Regex("(ST=)(.*?)(,|$)", RegexOptions.IgnoreCase | RegexOptions.Singleline);
            Regex rx_C = new Regex("(C=)(.*?)(,|$)", RegexOptions.IgnoreCase | RegexOptions.Singleline);
            Match m;

            foreach (string line in cInfo.FullInfo.Split('\n'))
            {
                if (line.Contains("Owner: "))
                {
                    m = rx_EMAIL.Match(line);
                    if (m.Success)
                        cInfo.OwnerEmail = m.Groups[2].ToString();
                    m = rx_CN.Match(line);
                    if (m.Success)
                        cInfo.OwnerCN = m.Groups[2].ToString();
                    m = rx_OU.Match(line);
                    if (m.Success)
                        cInfo.OwnerOU = m.Groups[2].ToString();
                    m = rx_O.Match(line);
                    if (m.Success)
                        cInfo.OwnerO = m.Groups[2].ToString();
                    m = rx_L.Match(line);
                    if (m.Success)
                        cInfo.OwnerL = m.Groups[2].ToString();
                    m = rx_ST.Match(line);
                    if (m.Success)
                        cInfo.OwnerST = m.Groups[2].ToString();
                    m = rx_C.Match(line);
                    if (m.Success)
                        cInfo.OwnerC = m.Groups[2].ToString();
                }
            }

            return cInfo;
        }
示例#5
0
        /// <summary>
        /// Парсинг информации о подписи из keytool
        /// </summary>
        /// <param name="Data">Выходные данные утилиты keytool</param>
        /// <returns>Структура с информацией о подписи</returns>
        public static CertInfo Parse(string Data)
        {
            //Извлекаем серийный номер
            string sNum = null;

            foreach (string line in Data.Split('\n'))
            {
                if (line.Contains(keyToolLine))
                {
                    sNum = line.Replace(keyToolLine, string.Empty);
                    break;
                }
            }

            if (sNum == null)
            {
                return(null);
            }

            //Если не нашли, создаем новый и добавляем его в коллекцию
            CertInfo cInfo = new CertInfo()
            {
                SerialNumber = sNum, FullInfo = Data
            };

            //Извлекаем инфу о владельце
            Regex rx_EMAIL = new Regex("(EMAILADDRESS=)(.*?)(,|$)", RegexOptions.IgnoreCase | RegexOptions.Singleline);
            Regex rx_CN    = new Regex("(CN=)(.*?)(,|$)", RegexOptions.IgnoreCase | RegexOptions.Singleline);
            Regex rx_OU    = new Regex("(OU=)(.*?)(,|$)", RegexOptions.IgnoreCase | RegexOptions.Singleline);
            Regex rx_O     = new Regex("(O=)(.*?)(,|$)", RegexOptions.IgnoreCase | RegexOptions.Singleline);
            Regex rx_L     = new Regex("(L=)(.*?)(,|$)", RegexOptions.IgnoreCase | RegexOptions.Singleline);
            Regex rx_ST    = new Regex("(ST=)(.*?)(,|$)", RegexOptions.IgnoreCase | RegexOptions.Singleline);
            Regex rx_C     = new Regex("(C=)(.*?)(,|$)", RegexOptions.IgnoreCase | RegexOptions.Singleline);
            Match m;

            foreach (string line in cInfo.FullInfo.Split('\n'))
            {
                if (line.Contains("Owner: "))
                {
                    m = rx_EMAIL.Match(line);
                    if (m.Success)
                    {
                        cInfo.OwnerEmail = m.Groups[2].ToString();
                    }
                    m = rx_CN.Match(line);
                    if (m.Success)
                    {
                        cInfo.OwnerCN = m.Groups[2].ToString();
                    }
                    m = rx_OU.Match(line);
                    if (m.Success)
                    {
                        cInfo.OwnerOU = m.Groups[2].ToString();
                    }
                    m = rx_O.Match(line);
                    if (m.Success)
                    {
                        cInfo.OwnerO = m.Groups[2].ToString();
                    }
                    m = rx_L.Match(line);
                    if (m.Success)
                    {
                        cInfo.OwnerL = m.Groups[2].ToString();
                    }
                    m = rx_ST.Match(line);
                    if (m.Success)
                    {
                        cInfo.OwnerST = m.Groups[2].ToString();
                    }
                    m = rx_C.Match(line);
                    if (m.Success)
                    {
                        cInfo.OwnerC = m.Groups[2].ToString();
                    }
                }
            }

            return(cInfo);
        }
示例#6
0
        /// <summary>
        /// Считывает информацию о текущей подписи из файла сертификата (*.pem или *.RSA)
        /// </summary>
        /// <param name="fPath">Путь до файла (*.pem или *.RSA)</param>
        /// <returns></returns>
        public static CertInfo ReadCert(string fPath, bool IsPk8Required)
        {
            if (!File.Exists(fPath))
            {
                return(null);
            }

            //Получаем вывод keytool
            string ktOutput = null;

            try
            {
                Environment.ktProc.StartInfo.Arguments = string.Format(Environment.keytoolArgs, fPath);
                Environment.Log(string.Format("Запускаем \"{0}\" с аргументами \"{1}\"", Environment.ktProc.StartInfo.FileName, Environment.ktProc.StartInfo.Arguments));
                Environment.ktProc.Start();
                ktOutput = Environment.ktProc.StandardOutput.ReadToEnd();
                Environment.ktProc.WaitForExit();
            }
            catch (Exception ex) {
                Environment.Log(string.Format("Запуск не удался. Ошибка: \"{0}\"", ex.Message));
                return(null);
            }

            //Если вывод пуст - фейл
            if (string.IsNullOrEmpty(ktOutput))
            {
                return(null);
            }

            //Парсим
            CertInfo cInfo = CertInfo.Parse(ktOutput);

            if (cInfo == null)
            {
                return(null);
            }

            //Проверяем наличие рядом файла pk8. Если есть - добавляем пути, тем самым помечаем пригодным для подписания
            string pk8File = Path.Combine(Path.GetDirectoryName(fPath), fPath.Substring(0, fPath.IndexOf('.')) + ".pk8");

            if (File.Exists(pk8File))
            {
                Environment.Log(string.Format("Найден pk8 \"{0}\". Добавляем как пригодный для подписи", pk8File));
                cInfo.pemPath = fPath;
                cInfo.pk8Path = pk8File;
                CertInfo cnInfoStored = SignCerts.Find(c => (c.SerialNumber == cInfo.SerialNumber && cInfo.pemPath == cInfo.pemPath && c.pk8Path == cInfo.pk8Path));
                if (cnInfoStored == null)
                {
                    SignCerts.Add(cInfo);
                    return(cInfo);
                }
                else
                {
                    return(cnInfoStored);
                }
            }
            else
            {
                if (IsPk8Required)
                {
                    Environment.Log(string.Format("Требуется pk8 \"{0}\", однако он не был найден.", pk8File));
                    return(null);
                }
            }

            //Ищем подпись в коллекции
            CertInfo cInfoStored = Certs.Find(c => (c.SerialNumber == cInfo.SerialNumber));

            if (cInfoStored == null)
            {
                Certs.Add(cInfo);
                return(cInfo);
            }
            else
            {
                return(cInfoStored);
            }
        }
示例#7
0
        /// <summary>
        /// Основная процедура подписывания файлов
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void bwSignFiles_DoWork(object sender, DoWorkEventArgs e)
        {
            //Блокируем интерфейс
            Block(true);
            StartButtonMode(true);
            int ErrorCounter = 0;

            int FileNum = 0;
            int FileCount = 0;
            foreach (PackageInfo pInfo in pReader.Packages)
                if (pInfo.NewCert.CanSign)
                    FileCount++;

            foreach (PackageInfo pInfo in pReader.Packages)
            {
                // ==================================================================================

                //Показываем статусную строку и скроллим к итему
                this.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal, new Action(delegate()
                {
                    PackagesLW.ScrollIntoView(pInfo);
                    pInfo.IsComboBoxVisible = false;
                }));

                //Пропускаем файлы с явно неуказанными сертификатами
                if (!pInfo.NewCert.CanSign)
                {
                    Environment.Log(string.Format("У файла \"{0}\" не выбран пригодный для подписи сертификат. Пропуск...", pInfo.Name));
                    this.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal, new Action(delegate() { pInfo.StatusText = STR_INLINE_SKIP; }));
                    continue;
                }

                // ==================================================================================

                //Устанавливаем статус подписи
                pInfo.StatusText = STR_INLINE_SIGNING;
                SetStatus(string.Format(STR_STATUS_SIGNING_FILE, pInfo.Path), FileNum, FileCount, false);
                //Подписываем
                string SignedFile = Signer.SignFile(pInfo);

                //Если нулл или пустая - фейл
                if (string.IsNullOrEmpty(SignedFile))
                {
                    ErrorCounter++;
                    this.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal, new Action(delegate() { pInfo.StatusText = STR_INLINE_SIGNING_ERROR; }));
                    continue;
                }

                //Также если файла нет - фейл
                if (!File.Exists(SignedFile))
                {
                    ErrorCounter++;
                    this.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal, new Action(delegate() { pInfo.StatusText = STR_INLINE_SIGNING_ERROR; }));
                    continue;
                }

                // ==================================================================================

                //Устанавливаем статус алигнинга
                pInfo.StatusText = STR_INLINE_ALIGNING;
                SetStatus(string.Format(STR_STATUS_ALIGNING_FILE, pInfo.Path), FileNum, FileCount, false);
                //Зипалигним
                string SignedAlignedFile = Aligner.AlignFile(SignedFile);

                //Если нулл или пустая - фейл
                if (string.IsNullOrEmpty(SignedAlignedFile))
                {
                    ErrorCounter++;
                    this.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal, new Action(delegate() { pInfo.StatusText = STR_INLINE_ALIGNING_ERROR; }));
                    continue;
                }

                //Также если файла нет - фейл
                if (!File.Exists(SignedAlignedFile))
                {
                    ErrorCounter++;
                    this.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal, new Action(delegate() { pInfo.StatusText = STR_INLINE_ALIGNING_ERROR; }));
                    continue;
                }

                // ==================================================================================

                //Устанавливаем статус копирования
                pInfo.StatusText = STR_INLINE_COPYING;
                SetStatus(string.Format(STR_STATUS_COPYING_FILE, pInfo.Path), FileNum, FileCount, false);

                Environment.Log(string.Format("Копируем временный файл \"{0}\" на исходное место \"{1}\"...", SignedAlignedFile, pInfo.Path));
                //Копируем на место
                try { File.Copy(SignedAlignedFile, pInfo.Path, true); }
                catch (Exception ex)
                {
                    ErrorCounter++;
                    Environment.Log(string.Format("Не удается скопировать файл \"{0}\" Ошибка: {1}", SignedAlignedFile, ex.Message));
                }

                // ==================================================================================

                //Устанавливаем статус очистки
                pInfo.StatusText = STR_INLINE_CLEANING;

                //удаляем мусор
                try
                {
                    File.Delete(SignedFile);
                    File.Delete(SignedAlignedFile);
                }
                catch (Exception ex) { Environment.Log(string.Format("Не удается удалить временные файлы. Ошибка: {0}", ex.Message)); }

                this.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal, new Action(delegate() { pInfo.StatusText = STR_INLINE_DONE; }));
                FileNum++;

                if (bwSignFiles.CancellationPending)
                {
                    Environment.Log("Вызвана остановка операции");
                    break;
                }
            }

            if (ErrorCounter > 0)
            {
                if (File.Exists(Environment.logFile))
                {
                    if (MessageBox.Show("Обработка некоторых файлов потерпела неудачу. Хотите посмотреть логи?", "Обработка некоторых файлов потерпела неудачу", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes)
                    {
                        this.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal, new Action(delegate()
                        {
                            CertInfoWindow ErrorInfo = new CertInfoWindow(File.ReadAllText(Environment.logFile), "Лог");
                            ErrorInfo.Show();
                        }));
                    }
                }
            }
            else if (IsZip && !bwSignFiles.CancellationPending) //Если указан зип и не сказано остановиться - пакуемся
            {

                //Спрашиваем куда сохранить
                bool result = false;
                this.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal, new Action(delegate() {
                    SaveZipBrowser.FileName = Path.GetFileNameWithoutExtension(ZipFile) + "_signed";
                    result = SaveZipBrowser.ShowDialog() == System.Windows.Forms.DialogResult.OK;
                }));
                if (result)
                {
                    //Получаем выбранный сертификат
                    CertInfo SignCert = new CertInfo();
                    this.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal, new Action(delegate() { SignCert = ((CertInfo)ZipSign.SelectedValue); }));
                    //И смотри требуется ли подпись
                    if (SignCert.CanSign)
                    {
                        //Если нужно, запаковываем сперва во временную папку
                        string tempZip = Path.Combine(Environment.TempPath, Path.GetFileNameWithoutExtension(SaveZipBrowser.FileName) + "_zipunsigned.zip");
                        PackZIP(ZipRootPath, tempZip);
                        //Создаем экземпляр пакета
                        PackageInfo zipPackage = new PackageInfo();
                        zipPackage.Path = tempZip;
                        zipPackage.IsChangeAllowed = true;
                        zipPackage.NewCert = SignCert;

                        //Устанавливаем статус подписи
                        SetStatus(string.Format(STR_STATUS_SIGNING_FILE, SaveZipBrowser.FileName), 100, 100, true);
                        //Подписываем пакет уже по указанному ранее пути
                        Signer.SignFile(zipPackage, SaveZipBrowser.FileName);

                        //Устанавливаем статус очистки
                        SetStatus(STR_INLINE_CLEANING, 100, 100, true);
                        //Удаляем мусор
                        try { File.Delete(tempZip); }
                        catch { }
                    }
                    else //Если подписывать не нужно, сразу запаковываем по указанному пути
                        PackZIP(ZipRootPath, SaveZipBrowser.FileName);
                }
            }

            this.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal, new Action(delegate() { pReader.ShowComboBoxes(); }));
            SetStatus(STR_STATUS_DONE, 0, 100, false);
            Block(false);
            StartButtonMode(false);
        }