コード例 #1
0
ファイル: Signer.cs プロジェクト: santedb/santedb-sdk
        /// <summary>
        /// Create a signed package
        /// </summary>
        public AppletPackage CreateSignedSolution(AppletSolution sln)
        {
            try
            {
                X509Certificate2 signCert = this.GetSigningCert();

                if (!signCert.HasPrivateKey)
                {
                    throw new InvalidOperationException($"You do not have the private key for certificiate {signCert.Subject}");
                }

                // Combine all the manifests
                sln.Meta.Hash           = SHA256.Create().ComputeHash(sln.Include.SelectMany(o => o.Manifest).ToArray());
                sln.Meta.PublicKeyToken = signCert.Thumbprint;

                if (this.m_parms.EmbedCertificate)
                {
                    sln.PublicKey = signCert.Export(X509ContentType.Cert);
                }

                if (!signCert.HasPrivateKey)
                {
                    throw new SecurityException($"Provided key {this.m_parms.SignKeyFile} has no private key");
                }
                RSACryptoServiceProvider rsa = signCert.PrivateKey as RSACryptoServiceProvider;
                sln.Meta.Signature = rsa.SignData(sln.Include.SelectMany(o => o.Manifest).ToArray(), CryptoConfig.MapNameToOID("SHA1"));
                return(sln);
            }
            catch (Exception e)
            {
                Emit.Message("ERROR", "Error signing package: {0}", e);
                return(null);
            }
        }
コード例 #2
0
        /// <summary>
        /// Install the specified applet solution
        /// </summary>
        /// <param name="solution"></param>
        /// <param name="isUpgrade"></param>
        /// <returns></returns>
        public bool Install(AppletSolution solution, bool isUpgrade = false)
        {
            this.m_tracer.TraceInfo("Installing solution {0}", solution.Meta);

            // TODO: Verify package hash / signature
            if (!this.VerifyPackage(solution))
            {
                throw new SecurityException("Applet failed validation");
            }

            this.m_appletCollection.Add(solution.Meta.Id, new AppletCollection());
            this.m_readonlyAppletCollection.Add(solution.Meta.Id, this.m_appletCollection[solution.Meta.Id].AsReadonly());
            this.m_readonlyAppletCollection[solution.Meta.Id].CollectionChanged += (o, e) => this.Changed?.Invoke(o, e);

            // Save the applet
            var appletDir = this.m_configuration.AppletDirectory;

            if (!Path.IsPathRooted(appletDir))
            {
                appletDir = Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), this.m_configuration.AppletDirectory);
            }

            if (!Directory.Exists(appletDir))
            {
                Directory.CreateDirectory(appletDir);
            }

            // Install
            var pakFile = Path.Combine(appletDir, solution.Meta.Id + ".pak");

            if (this.m_solutions.Any(o => o.Meta.Id == solution.Meta.Id) && File.Exists(pakFile) && !isUpgrade)
            {
                throw new InvalidOperationException($"Cannot replace {solution.Meta} unless upgrade is specifically specified");
            }

            // Unpack items from the solution package and install if needed
            foreach (var itm in solution.Include.Where(o => o.Manifest != null))
            {
                var installedApplet = this.GetApplet(solution.Meta.Id, itm.Meta.Id);
                if (installedApplet == null ||
                    new Version(installedApplet.Info.Version) < new Version(itm.Meta.Version)) // Installed version is there but is older or is not installed, so we install it
                {
                    this.m_tracer.TraceInfo("Installing Solution applet {0} v{1}...", itm.Meta.Id, itm.Meta.Version);
                    this.Install(itm, true, solution);
                }
            }

            // Register the pakfile
            lock (this.m_fileDictionary)
                if (!this.m_fileDictionary.ContainsKey(solution.Meta.Id + ".sln"))
                {
                    this.m_fileDictionary.Add(solution.Meta.Id + ".sln", pakFile);
                }

            this.m_solutions.Add(solution);

            return(true);
        }
コード例 #3
0
ファイル: Distributor.cs プロジェクト: santedb/santedb-sdk
        /// <summary>
        /// Package the assets
        /// </summary>
        /// <returns></returns>
        public int Package()
        {
            using (FileStream fs = File.OpenRead(this.m_parameters.Output))
                this.m_package = AppletSolution.Load(fs);

            // Package the android APK project
            if (this.m_parameters.DcdrAssets.Contains("android"))
            {
                this.PackageApk();
            }

            // Package the DCG project
            if (this.m_parameters.DcdrAssets.Contains("gateway"))
            {
                this.PackageDcg();
            }

            return(1);
        }
コード例 #4
0
ファイル: Composer.cs プロジェクト: santedb/santedb-sdk
        /// <summary>
        /// Compose multiple PAK files into a solution
        /// </summary>
        public int Compose()
        {
            try
            {
                AppletManifest mfst = null;
                using (FileStream fs = File.OpenRead(this.m_parms.Source))
                    mfst = AppletManifest.Load(fs);

                var slnPak = mfst.CreatePackage();

                AppletSolution sln = new AppletSolution();
                sln.Meta      = slnPak.Meta;
                sln.PublicKey = slnPak.PublicKey;
                sln.Manifest  = slnPak.Manifest;

                if (sln.Meta.Uuid == Guid.Empty)
                {
                    Emit.Message("WARN", "The package does not carry a UUID! You should add a UUID to your solution manifest");
                }
                sln.Include = new List <AppletPackage>();

                foreach (var pfile in sln.Meta.Dependencies.ToArray())
                {
                    AppletPackage pkg = null;
                    if (!String.IsNullOrEmpty(pfile.Version)) // specific version
                    {
                        pkg = PackageRepositoryUtil.GetFromAny(pfile.Id, new Version(pfile.Version));
                    }
                    else if (!String.IsNullOrEmpty(m_parms.Version))
                    {
                        pkg = PackageRepositoryUtil.GetFromAny(pfile.Id, new Version(m_parms.Version))
                              ?? PackageRepositoryUtil.GetFromAny(pfile.Id, null);
                    }
                    else
                    {
                        pkg = PackageRepositoryUtil.GetFromAny(pfile.Id, null);
                    }

                    if (pkg == null)
                    {
                        throw new KeyNotFoundException($"Package {pfile.Id} ({pfile.Version ?? m_parms.Version ?? "latest"}) not found");
                    }
                    else
                    {
                        Emit.Message("INFO", "Including {0} version {1}..", pkg.Meta.Id, pkg.Meta.Version);
                        sln.Meta.Dependencies.RemoveAll(o => o.Id == pkg.Meta.Id);

                        if (this.m_parms.Sign && pkg.Meta.Signature == null)
                        {
                            Emit.Message("WARN", "Package {0} is not signed, but you're signing your package. We'll sign it using your key", pkg.Meta.Id);
                            pkg = new Signer(this.m_parms).CreateSignedPackage(pkg.Unpack());
                        }
                        sln.Include.Add(pkg);
                    }
                }

                // Emit i18n file?
                if (!String.IsNullOrEmpty(this.m_parms.InternationalizationFile))
                {
                    Emit.Message("INFO", $"Writing string manifest to {this.m_parms.InternationalizationFile}");
                    using (var fs = File.Create(this.m_parms.InternationalizationFile))
                        using (var tw = new StreamWriter(fs, System.Text.Encoding.UTF8))
                        {
                            // tx translations
                            var mfsts         = sln.Include.Select(o => o.Unpack()).ToList();
                            var appletStrings = mfsts.SelectMany(o => o.Strings).ToArray();
                            var stringKeys    = appletStrings.SelectMany(o => o.String).Select(o => o.Key).Distinct();
                            var langs         = appletStrings.Select(o => o.Language).Distinct().ToArray();
                            tw.Write("key,");
                            tw.WriteLine(String.Join(",", langs));

                            foreach (var str in stringKeys)
                            {
                                tw.Write($"{str},");
                                foreach (var lang in langs)
                                {
                                    tw.Write($"\"{appletStrings.Where(o => o.Language == lang).SelectMany(s => s.String).FirstOrDefault(o => o.Key == str)?.Value}\",");
                                }
                                tw.WriteLine();
                            }
                        }
                }

                sln.Meta.Hash = SHA256.Create().ComputeHash(sln.Include.SelectMany(o => o.Manifest).ToArray());
                // Sign the signature package
                if (this.m_parms.Sign)
                {
                    new Signer(this.m_parms).CreateSignedSolution(sln);
                }

                // Now save
                using (FileStream fs = File.Create(this.m_parms.Output ?? Path.ChangeExtension(sln.Meta.Id, ".sln.pak")))
                    sln.Save(fs);

                return(0);
            }
            catch (System.Exception e)
            {
                Emit.Message("ERROR", e.Message);
                //Console.Error.WriteLine("Cannot compose solution {0}: {1}", this.m_parms.Source, e);
                return(-1);
            }
        }
コード例 #5
0
 /// <summary>
 /// Install a applet solution
 /// </summary>
 public bool Install(AppletSolution solution, bool isUpgrade = false)
 {
     throw new NotSupportedException();
 }
コード例 #6
0
 /// <summary>
 /// Create applet solution
 /// </summary>
 public AppletSolutionInfo CreateAppletSolution(AppletSolution solution)
 {
     return(this.Client.Post <AppletSolution, AppletSolutionInfo>("AppletSolution", solution));
 }
コード例 #7
0
 /// <summary>
 /// Initializes a new instance of the <see cref="AppletSolutionInfo"/> class
 /// with a specific applet manifest instance.
 /// </summary>
 public AppletSolutionInfo(AppletSolution soln, X509Certificate2Info publisher) : base(soln.Meta, publisher)
 {
     this.Include = soln.Include.Select(s => new AppletManifestInfo(s.Meta, null)).ToList();
 }
コード例 #8
0
        /// <summary>
        /// Performs an installation
        /// </summary>
        public bool Install(AppletPackage package, bool isUpgrade, AppletSolution owner)
        {
            this.m_tracer.TraceInfo("Installing {0}", package.Meta);


            var appletScope = owner?.Meta.Id ?? String.Empty;

            // TODO: Verify package hash / signature
            if (!this.VerifyPackage(package))
            {
                throw new SecurityException("Applet failed validation");
            }
            else if (!this.m_appletCollection[appletScope].VerifyDependencies(package.Meta))
            {
                this.m_tracer.TraceWarning($"Applet {package.Meta} depends on : [{String.Join(", ", package.Meta.Dependencies.Select(o => o.ToString()))}] which are missing or incompatible");
            }

            // Save the applet
            var appletDir = this.m_configuration.AppletDirectory;

            if (!Path.IsPathRooted(appletDir))
            {
                appletDir = Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), this.m_configuration.AppletDirectory);
            }
            if (owner != null)
            {
                appletDir = Path.Combine(appletDir, owner.Meta.Id);
            }
            if (!Directory.Exists(appletDir))
            {
                Directory.CreateDirectory(appletDir);
            }

            // Install
            var pakFile = Path.Combine(appletDir, package.Meta.Id + ".pak");

            if (this.m_appletCollection[appletScope].Any(o => o.Info.Id == package.Meta.Id) && File.Exists(pakFile) && !isUpgrade)
            {
                throw new InvalidOperationException($"Cannot replace {package.Meta} unless upgrade is specifically specified");
            }

            using (var fs = File.Create(pakFile))
            {
                package.Save(fs);
            }

            lock (this.m_fileDictionary)
                if (!this.m_fileDictionary.ContainsKey($"{appletScope}{package.Meta.Id}"))
                {
                    this.m_fileDictionary.Add($"{appletScope}{package.Meta.Id}", pakFile);
                }

            var pkg = package.Unpack();

            // remove the package from the collection if this is an upgrade
            if (isUpgrade)
            {
                this.m_appletCollection[appletScope].Remove(pkg);
            }

            this.m_appletCollection[appletScope].Add(pkg);

            // We want to install the templates & protocols into the DB
            this.m_tracer.TraceInfo("Installing templates...");

            // Install templates
            var idp = ApplicationServiceContext.Current.GetService <ITemplateDefinitionRepositoryService>();

            if (idp != null)
            {
                foreach (var itm in pkg.Templates)
                {
                    if (idp.GetTemplateDefinition(itm.Mnemonic) == null)
                    {
                        this.m_tracer.TraceInfo("Installing {0}...", itm.Mnemonic);
                        idp.Insert(new TemplateDefinition()
                        {
                            Oid         = itm.Oid,
                            Mnemonic    = itm.Mnemonic,
                            Description = itm.Description,
                            Name        = itm.Mnemonic
                        });
                    }
                }
            }

            AppletCollection.ClearCaches();

            return(true);
        }